---
sidebar_position: 9
title: Agents
description: Manage call center agents — create, update, delete agents and control their availability, avatar, and password via the Firetell REST API.
---

# Agents

Agents are members assigned to handle calls in a call center setup. Each agent has login credentials to access the agent portal at `https://{workspace_id}.firetell.app`, where they can receive and make calls. The Agents API allows you to manage agent accounts, availability status, and routing preferences.

## Endpoints

| Method   | Endpoint               | Description                    |
| -------- | ---------------------- | ------------------------------ |
| `GET`    | `/agents`              | List all agents                |
| `GET`    | `/agents/:id`          | Get agent details              |
| `GET`    | `/agents/:id/teams`    | List teams an agent belongs to |
| `POST`   | `/agents`              | Create an agent                |
| `PATCH`  | `/agents/:id`          | Update agent settings          |
| `PATCH`  | `/agents/:id/avatar`   | Upload agent avatar            |
| `PATCH`  | `/agents/:id/password` | Change agent password          |
| `DELETE` | `/agents/:id`          | Delete an agent                |

## The Agent Object

| Field          | Type           | Description                                       |
| -------------- | -------------- | ------------------------------------------------- |
| `id`           | string         | Unique agent identifier (prefixed with `ag_`)     |
| `username`     | string         | Agent login username (unique per workspace)       |
| `domain`       | string         | Agent's domain (e.g., `yourcompany.firetell.app`) |
| `display_name` | string         | Agent's display name                              |
| `email`        | string \| null | Agent's email address                             |
| `avatar`       | string \| null | URL to agent's avatar image                       |
| `state`        | string         | Current availability state                        |
| `is_active`    | boolean        | Whether the agent account is active               |
| `workspace_id` | string         | Workspace identifier                              |
| `country_code` | string         | Two-letter ISO country code (e.g., `VN`, `US`)    |
| `created_at`   | string         | ISO 8601 creation timestamp                       |
| `updated_at`   | string         | ISO 8601 last update timestamp                    |

### Agent States

| State       | Description                                |
| ----------- | ------------------------------------------ |
| `available` | Agent is online and ready to receive calls |
| `incall`    | Agent is currently on a call               |
| `busy`      | Agent is online but not accepting calls    |
| `offline`   | Agent is not logged in                     |

:::info
The `state` field is a **real-time presence** value powered by the presence system. It is **not stored in the database**. An agent is considered `available` if they are reachable via **any** channel — either a live WebSocket connection or a registered VoIP Push token (for mobile apps in background). An agent transitions to `offline` only when **all** reachability sources are removed (e.g., all WebSocket sessions closed **and** push token unregistered via [logout](/docs/rest-api/agent-api/account#logout)).
:::

:::info
The `password` field is never returned in API responses.
:::

---

## List Agents

```
GET /agents
```

Retrieve a paginated list of all agents in the workspace.

### Authentication

Requires `ApiKey` with any scope.

### Query Parameters

| Parameter      | Type    | Default      | Description                                                                         |
| -------------- | ------- | ------------ | ----------------------------------------------------------------------------------- |
| `page`         | number  | `1`          | Page number (min: 1)                                                                |
| `limit`        | number  | `10`         | Items per page (min: 1, max: 100)                                                   |
| `search`       | string  | —            | Search by display name, email, or username                                          |
| `sort_field`   | string  | `created_at` | Sort field. Allowed: `created_at`, `display_name`, `email`, `username`, `is_active` |
| `sort_order`   | string  | `desc`       | Sort order: `asc` or `desc`                                                         |
| `state`        | string  | —            | Filter by agent state: `available`, `incall`, `busy`, `offline`                     |
| `country_code` | string  | —            | Filter by country code (e.g., `VN`, `US`)                                           |
| `is_active`    | boolean | —            | Filter by active status                                                             |

### Request

```bash
curl -X GET "https://{workspace_id}.firetell.app/api/v1/agents?page=1&limit=10&state=available" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY"
```

### Response

```json
{
  "data": [
    {
      "id": "ag_7f3a2b1c9d4e5f6a8b0c1d2e",
      "username": "johndoe",
      "domain": "yourcompany.firetell.app",
      "display_name": "John Doe",
      "email": "john@example.com",
      "avatar": "https://s3.amazonaws.com/bucket/yourcompany/avatars/abc123.webp",
      "state": "available",
      "is_active": true,
      "workspace_id": "yourcompany",
      "country_code": "US",
      "created_at": "2026-01-15T08:30:00.000Z",
      "updated_at": "2026-03-20T14:00:00.000Z"
    }
  ],
  "meta": {
    "total": 25,
    "page": 1,
    "limit": 10,
    "total_pages": 3
  }
}
```

---

## Get Agent

```
GET /agents/:id
```

Retrieve details of a specific agent.

### Authentication

Requires `ApiKey` with any scope.

### Path Parameters

| Parameter | Type   | Description                                        |
| --------- | ------ | -------------------------------------------------- |
| `id`      | string | The agent ID (e.g., `ag_7f3a2b1c9d4e5f6a8b0c1d2e`) |

### Request

```bash
curl -X GET "https://{workspace_id}.firetell.app/api/v1/agents/ag_7f3a2b1c9d4e5f6a8b0c1d2e" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY"
```

### Response

```json
{
  "id": "ag_7f3a2b1c9d4e5f6a8b0c1d2e",
  "username": "johndoe",
  "domain": "yourcompany.firetell.app",
  "display_name": "John Doe",
  "email": "john@example.com",
  "avatar": null,
  "state": "offline",
  "is_active": true,
  "workspace_id": "yourcompany",
  "country_code": "US",
  "created_at": "2026-01-15T08:30:00.000Z",
  "updated_at": "2026-01-15T08:30:00.000Z"
}
```

### Error Response

```json
{
  "statusCode": 404,
  "message": "Agent not found",
  "error": "Not Found"
}
```

---

## List Agent Teams

```
GET /agents/:id/teams
```

Retrieve a paginated list of teams that a specific agent belongs to.

### Authentication

Requires `ApiKey` with any scope.

### Path Parameters

| Parameter | Type   | Description  |
| --------- | ------ | ------------ |
| `id`      | string | The agent ID |

### Query Parameters

| Parameter    | Type   | Default      | Description                 |
| ------------ | ------ | ------------ | --------------------------- |
| `page`       | number | `1`          | Page number                 |
| `limit`      | number | `10`         | Items per page (max: 100)   |
| `sort_field` | string | `created_at` | Sort field                  |
| `sort_order` | string | `desc`       | Sort order: `asc` or `desc` |

### Request

```bash
curl -X GET "https://{workspace_id}.firetell.app/api/v1/agents/ag_7f3a2b1c9d4e5f6a8b0c1d2e/teams" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY"
```

### Response

```json
{
  "data": [
    {
      "id": "te_a1b2c3d4e5f6a7b8c9d0e1f2",
      "name": "Support Team",
      "workspace_id": "yourcompany",
      "agent_count": 5,
      "created_at": "2026-01-10T09:00:00.000Z",
      "updated_at": "2026-02-15T10:30:00.000Z"
    },
    {
      "id": "te_b2c3d4e5f6a7b8c9d0e1f2a3",
      "name": "Sales Team",
      "workspace_id": "yourcompany",
      "agent_count": 8,
      "created_at": "2026-01-12T11:00:00.000Z",
      "updated_at": "2026-03-01T08:00:00.000Z"
    }
  ],
  "meta": {
    "total": 2,
    "page": 1,
    "limit": 10,
    "total_pages": 1
  }
}
```

---

## Create Agent

```
POST /agents
```

Create a new agent in the workspace. The agent will be able to log in to the agent portal and receive calls.

### Authentication

Requires `ApiKey` with `full` scope.

### Request Body

| Field          | Type    | Required | Description                                                                                                                                    |
| -------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `username`     | string  | ✅       | Login username. 3–30 characters, must start with a lowercase letter, only lowercase letters and numbers allowed. Must be unique per workspace. |
| `password`     | string  | ✅       | Login password. 6–50 characters.                                                                                                               |
| `display_name` | string  | ✅       | Agent display name. 3–50 characters. Only letters, spaces, and hyphens allowed.                                                                |
| `email`        | string  | —        | Email address. Must be unique per workspace.                                                                                                   |
| `avatar`       | string  | —        | URL to avatar image.                                                                                                                           |
| `country_code` | string  | —        | Two-letter ISO country code (e.g., `VN`). Defaults to workspace's country code.                                                                |
| `is_active`    | boolean | —        | Whether the agent is active. Defaults to `true`.                                                                                               |

### Request

```bash
curl -X POST "https://{workspace_id}.firetell.app/api/v1/agents" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "username": "janedoe",
    "password": "securePass123",
    "display_name": "Jane Doe",
    "email": "jane@example.com",
    "country_code": "VN"
  }'
```

### Response

```json
{
  "id": "ag_9a8b7c6d5e4f3a2b1c0d9e8f",
  "username": "janedoe",
  "domain": "yourcompany.firetell.app",
  "display_name": "Jane Doe",
  "email": "jane@example.com",
  "avatar": null,
  "state": "offline",
  "is_active": true,
  "workspace_id": "yourcompany",
  "country_code": "VN",
  "created_at": "2026-07-09T08:00:00.000Z",
  "updated_at": "2026-07-09T08:00:00.000Z"
}
```

### Error Responses

**Duplicate username:**

```json
{
  "statusCode": 409,
  "message": "username is exists",
  "error": "Conflict"
}
```

**Duplicate email:**

```json
{
  "statusCode": 409,
  "message": "email is exists",
  "error": "Conflict"
}
```

**Invalid username format:**

```json
{
  "statusCode": 400,
  "message": [
    "Invalid username. Must start with a lowercase letter, contain only lowercase letters, numbers"
  ],
  "error": "Bad Request"
}
```

---

## Update Agent

```
PATCH /agents/:id
```

Update an existing agent's settings. Only include the fields you want to change.

### Authentication

Requires `ApiKey` with `full` scope.

### Path Parameters

| Parameter | Type   | Description  |
| --------- | ------ | ------------ |
| `id`      | string | The agent ID |

### Request Body

All fields are optional:

| Field          | Type    | Description                                                                             |
| -------------- | ------- | --------------------------------------------------------------------------------------- |
| `username`     | string  | New username. 3–30 characters, lowercase letters, numbers, and hyphens. Must be unique. |
| `display_name` | string  | New display name. 1–35 characters. Only letters, spaces, and hyphens.                   |
| `email`        | string  | New email address. Must be unique per workspace.                                        |
| `avatar`       | string  | URL to new avatar image.                                                                |
| `is_active`    | boolean | Enable or disable the agent account.                                                    |
| `country_code` | string  | Two-letter ISO country code.                                                            |

### Request

```bash
curl -X PATCH "https://{workspace_id}.firetell.app/api/v1/agents/ag_7f3a2b1c9d4e5f6a8b0c1d2e" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "John D",
    "is_active": false
  }'
```

### Response

Returns the updated agent object:

```json
{
  "id": "ag_7f3a2b1c9d4e5f6a8b0c1d2e",
  "username": "johndoe",
  "domain": "yourcompany.firetell.app",
  "display_name": "John D",
  "email": "john@example.com",
  "avatar": null,
  "state": "offline",
  "is_active": false,
  "workspace_id": "yourcompany",
  "country_code": "US",
  "created_at": "2026-01-15T08:30:00.000Z",
  "updated_at": "2026-07-09T09:15:00.000Z"
}
```

### Error Response

```json
{
  "statusCode": 400,
  "message": "Agent not found or does not belong to this workspace",
  "error": "Bad Request"
}
```

---

## Upload Agent Avatar

```
PATCH /agents/:id/avatar
```

Upload or replace an agent's avatar image. The previous avatar (if any) will be automatically deleted from storage.

### Authentication

Requires `ApiKey` with `full` scope.

### Request Body

This endpoint uses `multipart/form-data` (not JSON).

| Field  | Type | Required | Description                                            |
| ------ | ---- | -------- | ------------------------------------------------------ |
| `file` | file | ✅       | Image file (max **5 MB**). Must be an image MIME type. |

### Supported Formats

| Format | MIME Type    |
| ------ | ------------ |
| JPEG   | `image/jpeg` |
| PNG    | `image/png`  |
| WebP   | `image/webp` |
| GIF    | `image/gif`  |

### Request

```bash
curl -X PATCH "https://{workspace_id}.firetell.app/api/v1/agents/ag_7f3a2b1c9d4e5f6a8b0c1d2e/avatar" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY" \
  -F "file=@/path/to/avatar.jpg"
```

### Response

Returns the updated agent object with the new `avatar` URL:

```json
{
  "id": "ag_7f3a2b1c9d4e5f6a8b0c1d2e",
  "username": "johndoe",
  "domain": "yourcompany.firetell.app",
  "display_name": "John Doe",
  "email": "john@example.com",
  "avatar": "https://s3.amazonaws.com/bucket/yourcompany/avatars/new-uuid.webp",
  "state": "available",
  "is_active": true,
  "workspace_id": "yourcompany",
  "country_code": "US",
  "created_at": "2026-01-15T08:30:00.000Z",
  "updated_at": "2026-07-09T10:00:00.000Z"
}
```

### Error Responses

**Missing file:**

```json
{
  "statusCode": 400,
  "message": "file is required",
  "error": "Bad Request"
}
```

**Invalid file type:**

```json
{
  "statusCode": 400,
  "message": "Only images accepted",
  "error": "Bad Request"
}
```

---

## Change Agent Password

```
PATCH /agents/:id/password
```

Change an agent's login password.

### Authentication

Requires `ApiKey` with `full` scope.

### Path Parameters

| Parameter | Type   | Description  |
| --------- | ------ | ------------ |
| `id`      | string | The agent ID |

### Request Body

| Field      | Type   | Required | Description                    |
| ---------- | ------ | -------- | ------------------------------ |
| `password` | string | ✅       | New password. 6–50 characters. |

### Request

```bash
curl -X PATCH "https://{workspace_id}.firetell.app/api/v1/agents/ag_7f3a2b1c9d4e5f6a8b0c1d2e/password" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "password": "newSecurePass456"
  }'
```

### Response

Returns the agent object (prior to update):

```json
{
  "id": "ag_7f3a2b1c9d4e5f6a8b0c1d2e",
  "username": "johndoe",
  "domain": "yourcompany.firetell.app",
  "display_name": "John Doe",
  "email": "john@example.com",
  "state": "offline",
  "is_active": true,
  "workspace_id": "yourcompany",
  "country_code": "US",
  "created_at": "2026-01-15T08:30:00.000Z",
  "updated_at": "2026-07-09T10:30:00.000Z"
}
```

:::caution
Changing an agent's password will not terminate active sessions. The agent will need to use the new password on their next login.
:::

---

## Delete Agent

```
DELETE /agents/:id
```

Permanently delete an agent from the workspace. The agent will be automatically removed from all teams they belong to, and team member counts will be updated accordingly.

### Authentication

Requires `ApiKey` with `full` scope.

:::caution
This action is irreversible. The agent will lose access to the call center portal immediately. Any active calls will not be affected, but the agent will not be able to receive new calls.
:::

### Path Parameters

| Parameter | Type   | Description  |
| --------- | ------ | ------------ |
| `id`      | string | The agent ID |

### Request

```bash
curl -X DELETE "https://{workspace_id}.firetell.app/api/v1/agents/ag_7f3a2b1c9d4e5f6a8b0c1d2e" \
  -H "Authorization: ApiKey sk-YOUR_API_KEY"
```

### Response

Returns the deleted agent object:

```json
{
  "id": "ag_7f3a2b1c9d4e5f6a8b0c1d2e",
  "username": "johndoe",
  "domain": "yourcompany.firetell.app",
  "display_name": "John Doe",
  "email": "john@example.com",
  "avatar": null,
  "state": "offline",
  "is_active": true,
  "workspace_id": "yourcompany",
  "country_code": "US",
  "created_at": "2026-01-15T08:30:00.000Z",
  "updated_at": "2026-07-09T08:00:00.000Z"
}
```

### Error Response

```json
{
  "statusCode": 400,
  "message": "Agent not found or does not belong to this workspace",
  "error": "Bad Request"
}
```
