> ## Documentation Index
> Fetch the complete documentation index at: https://docs.roserx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Passing Your Own User ID

> Attach your platform's user ID to a RoseRx conversation, so the conversation can be matched back to the right person in your own records.

If your platform already knows who the person using the widget is, you can pass your own user ID to RoseRx. RoseRx stores that ID against the conversation, so you can line the conversation up with the right person in your system later.

The ID is completely opaque to RoseRx. It is never shown to the visitor, never used to look anything up, and never used to grant access. It is only a reference you can reconcile against your own records.

## When to use this

Pass your own user ID when the widget is embedded somewhere the person is already signed in or already identified. For example:

* A patient or member portal where the visitor has logged in.
* A partner platform that hosts the widget inside its own signed-in experience.
* A page reached from a personalized link, where you already know who clicked.

If your widget sits on a public page where visitors are anonymous, you do not need this. Skip it and let RoseRx track the session on its own.

## Before you start

* Your widget is **saved** and its status is **Active**.
* The RoseRx embed script is already installed on your page. See [Embedding Your Widget](/guides/widgets/embedding).
* You have a stable, non-identifying user ID available from your own system.

<Warning>
  Do not use a person's email address, full name, date of birth, medical record number, or any other value that identifies them directly. Use the internal, meaningless ID your own system already has — for example `user_8f3c21` or a UUID. Anyone who views the page source can read the ID, so it must not reveal anything about the person on its own.
</Warning>

## Two ways to pass the ID

Pick whichever matches when your page learns who the person is. You can also use both together: the embed code sets a starting value and the JavaScript call replaces it later.

### Option A: Set the ID in the embed code

Use this when your page already knows who the person is at the moment it is rendered, such as a server-rendered portal page.

Add a `data-external-user-id` attribute to the RoseRx script tag. Everything else about your embed code stays exactly as it is.

```html theme={null}
<script
  src="https://app.roserx.ai/embed.js"
  data-widget="YOUR_WIDGET_ID"
  data-external-user-id="user_8f3c21"
></script>
```

<Tip>
  In a templating language this is a one-line change, for example:

  ```html theme={null}
  data-external-user-id="{{ current_user.id }}"
  ```

  Render an empty attribute, or leave the attribute off entirely, for visitors who are not signed in.
</Tip>

### Option B: Set the ID after the page loads

Use this when you only learn who the person is after the page has loaded, such as after a sign-in step or after your own API call returns.

The embed script publishes one function on the page, `window.RoseRx.setExternalUserId()`. Call it with the ID as soon as you have it.

<Steps>
  <Step title="Wait until the embed script has loaded">
    `window.RoseRx` only exists once `embed.js` has finished loading. Either call the function from the script tag's own `onload` handler, or guard the call with `if (window.RoseRx)`.

    ```html theme={null}
    <script
      src="https://app.roserx.ai/embed.js"
      data-widget="YOUR_WIDGET_ID"
      onload="window.RoseRx.setExternalUserId('user_8f3c21')"
    ></script>
    ```
  </Step>

  <Step title="Call it as soon as the person is known">
    Pass the ID the moment you have it, ideally before the visitor sends their first message. The ID is attached to the next message the visitor sends.

    ```javascript theme={null}
    // Guard the call in case the embed script is still loading.
    // A missing guard throws "window.RoseRx is undefined".
    const user = await signIn(credentials);

    if (window.RoseRx) {
      window.RoseRx.setExternalUserId(user.id);
    }
    ```
  </Step>

  <Step title="Clear it when the person signs out">
    Calling the function with no value, `null`, or an empty string stops RoseRx sending the ID from that point on. It does **not** remove an ID already stored against an existing conversation.

    ```javascript theme={null}
    window.RoseRx.setExternalUserId(null);
    ```
  </Step>
</Steps>

## What makes a valid ID

RoseRx checks the ID before sending it. Keep to these rules and it is always accepted.

| Rule                   | Detail                                                                                                   |
| ---------------------- | -------------------------------------------------------------------------------------------------------- |
| **Length**             | Between 1 and 255 characters                                                                             |
| **Allowed characters** | Printable ASCII with no spaces — letters, digits, and punctuation such as `_`, `-`, `.`, `:` and `@`     |
| **Not allowed**        | Spaces, tabs or line breaks anywhere in the value; empty values; accented or non-Latin characters; emoji |
| **Format**             | Text. `setExternalUserId()` also accepts a whole number and sends it as text                             |

Spaces *around* the value are trimmed for you, so `" user_8f3c21 "` is sent as `user_8f3c21`. Spaces *inside* the value are not allowed and the whole ID is rejected.

<Warning>
  If the ID breaks one of these rules, RoseRx ignores it and writes a warning to the browser console, such as `RoseRx: external user ID must be 1-255 printable characters with no spaces; ignoring it.` The widget keeps working normally and the visitor sees nothing unusual, so a mistake in your ID never breaks chat for them. It also means a broken ID is invisible from the outside — always check the console when testing.
</Warning>

## How the ID is stored

RoseRx keeps the **first** ID a conversation receives, and ignores any different ID sent later on that same conversation.

| Message        | ID sent       | Result                     |
| -------------- | ------------- | -------------------------- |
| First message  | No ID sent    | Nothing stored             |
| Second message | `user_8f3c21` | Stored on the conversation |
| Third message  | `user_44b910` | Ignored, first ID kept     |

This matters in a few everyday situations:

* **A returning visitor.** Conversations continue across page loads, so a visitor who comes back to an in-progress conversation keeps the ID it already carries.
* **Anonymous first, signed in later.** If a visitor starts chatting before you know who they are, that conversation stays unidentified. Setting an ID afterwards does not go back and label the earlier messages — it applies to the next new conversation.
* **A shared device.** If one person signs out and another signs in, the first person's conversation is not relabeled with the second person's ID. This is deliberate: an ID used for matching records must never quietly switch to a different person mid-conversation.

<Info>
  **The practical rule:** pass nothing until you actually know who the person is. Setting an ID too early, or setting a placeholder, is worse than setting it late — because the first value is the one that sticks.
</Info>

## Where the ID appears

The ID is stored on the conversation record in RoseRx.

<Note>
  The ID is not yet displayed in the Conversations view or included in conversation exports. If you need conversations matched back against your own user records, speak to your RoseRx contact. Surfacing the ID in the dashboard is planned for a future release.
</Note>

## Privacy and security

* **The ID is not a login or a permission.** RoseRx does not verify it and it grants no access to anything. Never pass a session token, API key, password, or anything else that would be sensitive if it leaked.
* **The ID is visible on the page.** It sits in the page's HTML or JavaScript, so treat it as public. Use an opaque internal ID that means nothing outside your own system.
* **The ID is stored exactly as received.** RoseRx does not alter, shorten or repair it, so whatever you send is what is kept. Send an email address and an email address is what is stored.
* **Domain restrictions still apply.** Passing an ID does not change which sites are allowed to load your widget.

## Troubleshooting

<Accordion title="Nothing seems to be recorded against my user ID">
  * Open the browser console and look for a `RoseRx:` warning. That means the ID broke one of the validation rules above and was ignored.
  * Check the ID for spaces. A value like `user 8f3c21` is rejected outright.
  * Confirm you are looking at a **new** conversation. An existing conversation keeps the first ID it received, so testing in a window that already has chat history will not pick up a new ID.
  * Confirm the widget status is **Active** and that chat itself is working.
</Accordion>

<Accordion title="The console says window.RoseRx is undefined">
  * The embed script had not finished loading when your code ran. Move the call into the script tag's `onload` handler, guard it with `if (window.RoseRx)`, or use the `data-external-user-id` attribute instead.
</Accordion>

<Accordion title="I set the ID but the conversation shows a different one">
  * Another ID reached that conversation first and was kept. Start a new conversation to test, and make sure nothing on the page sets a placeholder value before the real ID is known.
  * If you called `setExternalUserId()` again with an ID that breaks the validation rules, that call is ignored and the ID you set before stays in place. An invalid value does not clear the earlier ID. To clear it, call `setExternalUserId(null)`.
</Accordion>
