# Working with End Users
URL: /docs/embeddable/end-users
LLM index: /llms.txt
Description: Provision End Users via the API, generate short-lived JWTs for embedded components, and attribute messages to users.

# Working with End Users

An End User is a person in your application who sends and receives messages through Surge's embeddable UI components. End Users are distinct from Dashboard Users (people who log in to `hq.surge.app`). If you're building a SaaS platform where your customers interact with Surge-powered messaging, your customers' customers are End Users.

## What an End User is

End Users are provisioned via the Surge API and belong to a specific account. They're used in two ways:

1. **Embedded UI**: the inbox and conversation components authenticate as a specific End User, showing that user's conversations and sending messages on their behalf
2. **Message attribution**: messages sent or received on behalf of an End User include a `user_id` field, so you can trace activity back to the individual

End Users do not have Surge passwords or sessions. Authentication for embedded components goes through a short-lived JWT that your server generates.

## Provision an End User

Create an End User via the API before you mount any components for them:

<CodeGroup items={["Python","TypeScript","Ruby","Elixir","cURL"]}>

```python Python
from surge import Surge

surge = Surge()

user = surge.users.create(
    account_id="{account_id}",
    first_name="Jordan",
    last_name="Patel",
    metadata={"internal_user_id": "u_9887"},
)
```

```typescript TypeScript
import Surge from "@surgeapi/node";

const surge = new Surge();

const user = await surge.users.create("{account_id}", {
  first_name: "Jordan",
  last_name: "Patel",
  metadata: { internal_user_id: "u_9887" },
});
```

```ruby Ruby
require "surge_api"

surge = SurgeAPI::Client.new

user = surge.users.create(
  "{account_id}",
  first_name: "Jordan",
  last_name: "Patel",
  metadata: { "internal_user_id" => "u_9887" }
)
```

```elixir Elixir
client = Surge.Client.new(System.get_env("SURGE_API_KEY"))

{:ok, user} =
  Surge.Users.create(client, "{account_id}", %{
    first_name: "Jordan",
    last_name: "Patel",
    metadata: %{internal_user_id: "u_9887"}
  })
```

```bash cURL
curl -X POST https://api.surge.app/accounts/{account_id}/users \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "first_name": "Jordan",
    "last_name": "Patel",
    "metadata": {
      "internal_user_id": "u_9887"
    }
  }'
```

</CodeGroup>

```json
{
  "id": "usr_01jrzhe8d9enptypyx360pcmxu",
  "first_name": "Jordan",
  "last_name": "Patel",
  "metadata": {
    "internal_user_id": "u_9887"
  }
}
```

Store the returned `id` alongside the user's record in your database. You'll use it to generate component tokens and attribute messages.

## Generate a component token

Your server generates a short-lived JWT for each user session. The JWT scopes the embedded component to that specific user's data.

The simplest path is the token endpoint:

<CodeGroup items={["Python","TypeScript","Ruby","Elixir","cURL"]}>

```python Python
response = surge.users.create_token(user_id="{user_id}")
token = response.token
```

```typescript TypeScript
const response = await surge.users.createToken("{user_id}");
const token = response.token;
```

```ruby Ruby
response = surge.users.create_token("{user_id}")
token = response.token
```

```elixir Elixir
{:ok, token} = Surge.Users.create_token(client, "{user_id}", %{})
```

```bash cURL
curl -X POST https://api.surge.app/users/{user_id}/tokens \
  -H "Authorization: Bearer YOUR_API_KEY"
```

</CodeGroup>

```json
{
  "token": "eyJhbGciOiJFZERTQSIsImtpZCI6InNnbl8wMWouLi4ifQ..."
}
```

Return this token to your frontend and use it to mount the component. Generate a new token on each page load, tokens are short-lived.

## Typical vertical SaaS flow

1. When a customer signs up for your SaaS product, create a Surge End User via `POST /accounts/{account_id}/users`. Store the `id`.
2. When that customer loads a page in your app that includes embedded messaging, your server calls `POST /users/{user_id}/tokens` to get a fresh JWT.
3. Your frontend receives the JWT and mounts the Surge Inbox or Conversation component with it.
4. The component shows only that user's conversations and sends messages attributed to them.

```python
# On page load, server-side
@app.get("/api/surge-token")
async def get_surge_token(current_user: User):
    response = surge.users.create_token(id=current_user.surge_user_id)
    return {"token": response.token}
```

```javascript
// In the browser
const { token } = await fetch("/api/surge-token").then(r => r.json());
SurgeEmbed.mount("inbox", {
  target: document.getElementById("surge-inbox"),
  token,
});
```

## List and manage End Users

<CodeGroup items={["Python","TypeScript","Ruby","Elixir","cURL"]}>

```python Python
# List users in an account
for user in surge.users.list(account_id="{account_id}"):
    print(user.id)

# Update a user
surge.users.update("{user_id}", first_name="Jordan M.")

# Delete a user
surge.users.delete("{user_id}")
```

```typescript TypeScript
// List users in an account
for await (const user of await surge.users.list("{account_id}")) {
  console.log(user.id);
}

// Update a user
await surge.users.update("{user_id}", { first_name: "Jordan M." });

// Delete a user
await surge.users.delete("{user_id}");
```

```ruby Ruby
# List users in an account
page = surge.users.list("{account_id}")
page.data.each { |u| puts u.id }

# Update a user
surge.users.update("{user_id}", first_name: "Jordan M.")

# Delete a user
surge.users.delete("{user_id}")
```

```elixir Elixir
# Surge.Users.list isn't typed in the Elixir SDK yet — use the raw client.
{:ok, page} =
  Surge.Client.request(client, :get, "/accounts/{account_id}/users")

Enum.each(page["data"], fn u -> IO.puts(u["id"]) end)

# Update a user
{:ok, _} = Surge.Users.update(client, "{user_id}", %{first_name: "Jordan M."})

# Delete a user
{:ok, _} = Surge.Users.delete(client, "{user_id}")
```

```bash cURL
# List users in an account
curl "https://api.surge.app/accounts/{account_id}/users" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Update a user
curl -X PATCH https://api.surge.app/users/{user_id} \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "first_name": "Jordan M." }'

# Delete a user
curl -X DELETE https://api.surge.app/users/{user_id} \
  -H "Authorization: Bearer YOUR_API_KEY"
```

</CodeGroup>

Deleting an End User removes their Surge record but does not delete message history.

## Next steps

<CardGroup cols={3}>
  <Card title="Inbox component" icon="inbox" href="./inbox">
    Mount a conversation list for the current End User.
  </Card>
  <Card title="Conversation component" icon="comment" href="./conversation">
    Mount a single threaded conversation view.
  </Card>
  <Card title="Unread Count component" icon="bell" href="./unread-count">
    Show a live unread badge in your navigation.
  </Card>
</CardGroup>
