LiveKit docs › Agents framework › Agent dispatch service API

---

# AgentDispatchService API

> Use LiveKit's AgentDispatchService API to explicitly dispatch agents to rooms from your backend.

## Overview

Use this API to control which agents join which rooms and when, rather than relying on automatic dispatch.

These APIs are available via server SDKs and the LiveKit CLI:

- [Go AgentDispatch client](https://pkg.go.dev/github.com/livekit/server-sdk-go/v2#AgentDispatchClient)
- [Node.js AgentDispatch client](https://docs.livekit.io/reference/server-sdk-js/classes/AgentDispatchClient.html.md)
- [Python AgentDispatch client](https://docs.livekit.io/reference/python/livekit/api/agent_dispatch_service.html.md)
- [Ruby AgentDispatch client](https://github.com/livekit/server-sdk-ruby/blob/main/lib/livekit/agent_dispatch_service_client.rb)
- [Kotlin AgentDispatch client](https://github.com/livekit/server-sdk-kotlin/blob/main/src/main/kotlin/io/livekit/server/AgentDispatchServiceClient.kt)
- [LiveKit CLI](https://github.com/livekit/livekit-cli/blob/main/cmd/lk/dispatch.go)

To learn more about how agent dispatch works, see [Agent dispatch](https://docs.livekit.io/agents/server/agent-dispatch.md).

## Implementation details

LiveKit provides [server SDKs](https://docs.livekit.io/reference.md#server-apis) that make it easy to use these APIs. You can also implement your own client using the details in the following sections.

### Endpoints

The AgentDispatchService API is built with [Twirp](https://twitchtv.github.io/twirp/docs/intro.html). Arguments are passed as JSON to an endpoint using the POST method.

The AgentDispatchService API is accessible via `/twirp/livekit.AgentDispatchService/<MethodName>`. For example:

```shell
https://%{projectDomain}%/twirp/livekit.AgentDispatchService/CreateDispatch

```

### Authorization header

All endpoints require a signed access token with `roomAdmin` permission. Set the token via HTTP header:

```
Authorization: Bearer <token>

```

LiveKit server SDKs automatically include the above header.

To generate a token using the LiveKit CLI:

```shell
export TOKEN=$(lk token create \
  --api-key "$LIVEKIT_API_KEY" \
  --api-secret "$LIVEKIT_API_SECRET" \
  --room "my-room" \
  --admin | grep "Access token:" | awk '{print $3}')

```

> ℹ️ **Extract only the JWT**
> 
> The `lk token create` command outputs human-readable grant information alongside the token. Pipe through `grep` and `awk` as shown above to capture only the JWT.
> 
> Omit `--room` to generate a token with server-wide `roomAdmin` access, which allows dispatching to any room.

### Post body

Twirp expects an HTTP POST request. The body must be a JSON object (`application/json`) containing parameters specific to that request.

For example, the following creates a dispatch for agent `my-agent` in room `my-room`:

```shell
curl -X POST https://%{projectDomain}%/twirp/livekit.AgentDispatchService/CreateDispatch \
	-H "Authorization: Bearer $TOKEN" \
	-H 'Content-Type: application/json' \
	-d '{ "agent_name": "my-agent", "room": "my-room" }'

```

When passing in parameters, the server accepts either `snake_case` or `camelCase` for keys.

## AgentDispatchService APIs

The AgentDispatchService API allows you to create, delete, and list agent dispatches.

> 💡 **Tip**
> 
> All RPC definitions can be found in [livekit_agent_dispatch.proto](https://github.com/livekit/protocol/blob/main/protobufs/livekit_agent_dispatch.proto).

### CreateDispatch

Explicitly dispatch a named agent to a room. Requires `roomAdmin` permission.

If the room doesn't exist, it's created automatically.

Returns [AgentDispatch](#agentdispatch).

| Parameter | Type | Required | Description |
| agent_name | string | yes | Name of the agent to dispatch. Must match the `agent_name` set in the agent server. |
| room | string | yes | Name of the room to dispatch the agent to. |
| metadata | string |  | Optional metadata to pass to the agent. Opaque to LiveKit. |
| restart_policy | [JobRestartPolicy](#jobrestartpolicy) |  | Controls whether the job is restarted if it fails. Cloud only. Defaults to `JRP_ON_FAILURE`. |

### DeleteDispatch

Delete an existing agent dispatch. Requires `roomAdmin` permission.

Returns [AgentDispatch](#agentdispatch).

| Parameter | Type | Required | Description |
| dispatch_id | string | yes | ID of the dispatch to delete. |
| room | string | yes | Name of the room the dispatch belongs to. |

### ListDispatch

List agent dispatches for a room. Requires `roomAdmin` permission.

Returns [ListAgentDispatchResponse](#listagentdispatchresponse).

| Parameter | Type | Required | Description |
| room | string | yes | Name of the room to list dispatches for. |
| dispatch_id | string |  | If set, only the dispatch with this ID is returned. |

## Types

The AgentDispatchService API includes the following types.

### AgentDispatch

Represents a single agent dispatch.

| Field | Type | Description |
| id | string | Unique identifier for this dispatch. |
| agent_name | string | Name of the dispatched agent. |
| room | string | Name of the room the agent is dispatched to. |
| metadata | string | User-specified metadata, opaque to LiveKit. |
| state | [AgentDispatchState](#agentdispatchstate) | Current state of the dispatch. |
| restart_policy | [JobRestartPolicy](#jobrestartpolicy) | Restart policy for this dispatch. Cloud only. |

### AgentDispatchState

The current state of an agent dispatch.

| Field | Type | Description |
| jobs | List<[Job](#job)> | Jobs associated with this dispatch. For room-type dispatches, there is at most one job. For publisher-type dispatches, there is one job per publisher. |
| created_at | int64 | Unix timestamp (seconds) when the dispatch was created. |
| deleted_at | int64 | Unix timestamp (seconds) when the dispatch was deleted. Zero if not yet deleted. |

### ListAgentDispatchResponse

Returned by [ListDispatch](#listdispatch), containing all dispatches matching the request.

| Field | Type | Description |
| agent_dispatches | List<[AgentDispatch](#agentdispatch)> | List of agent dispatches matching the request. |

### Job

Represents a single agent job. Defined in [livekit_agent.proto](https://github.com/livekit/protocol/blob/main/protobufs/livekit_agent.proto). Nested types `Room` and `ParticipantInfo` are defined in [livekit_models.proto](https://github.com/livekit/protocol/blob/main/protobufs/livekit_models.proto).

| Field | Type | Description |
| id | string | Unique identifier for this job. |
| dispatch_id | string | ID of the dispatch that created this job. |
| type | [JobType](#jobtype) | Whether this job is assigned to the room (`JT_ROOM`) or per publisher (`JT_PUBLISHER`). |
| room | Room | Room the job is running in. |
| participant | ParticipantInfo | Participant associated with the job. Only set for publisher-type jobs. |
| metadata | string | Metadata passed during dispatch. |
| agent_name | string | Name of the agent handling this job. |
| state | [JobState](#jobstate) | Current state of the job. |
| enable_recording | bool | Whether Egress recording is enabled for this job. |

### JobState

Tracks the runtime status and timing of a job from assignment through completion. Defined in [livekit_agent.proto](https://github.com/livekit/protocol/blob/main/protobufs/livekit_agent.proto).

| Field | Type | Description |
| status | [JobStatus](#jobstatus) | Current status of the job. |
| error | string | Error message if the job failed. |
| started_at | int64 | Unix timestamp (seconds) when the job started. |
| ended_at | int64 | Unix timestamp (seconds) when the job ended. Zero if still running. |
| updated_at | int64 | Unix timestamp (seconds) when the job state was last updated. |
| participant_identity | string | Identity of the participant associated with this job. |
| worker_id | string | ID of the worker handling this job. |
| agent_id | string | ID of the agent instance handling this job. |

### JobType

The type of a job, determining how agents are assigned to participants. Defined in [livekit_agent.proto](https://github.com/livekit/protocol/blob/main/protobufs/livekit_agent.proto).

| Value | Description |
| JT_ROOM | The agent is assigned to the room. At most one job per dispatch. |
| JT_PUBLISHER | The agent is assigned per publisher. One job is created for each participant who publishes a track. |

### JobStatus

The current execution status of a job. Defined in [livekit_agent.proto](https://github.com/livekit/protocol/blob/main/protobufs/livekit_agent.proto).

| Value | Description |
| JS_PENDING | The job has been created but not yet started. |
| JS_RUNNING | The job is actively running. |
| JS_SUCCESS | The job completed successfully. |
| JS_FAILED | The job failed. |

### JobRestartPolicy

Controls whether a failed job is restarted. Cloud only.

| Value | Description |
| JRP_ON_FAILURE | Restart the job if it fails. This is the default. |
| JRP_NEVER | Never restart the job, even if it fails. |

---

This document was rendered at 2026-06-07T11:33:41.058Z.
For the latest version of this document, see [https://docs.livekit.io/reference/agents/agent-dispatch-service-api.md](https://docs.livekit.io/reference/agents/agent-dispatch-service-api.md).

To explore all LiveKit documentation, see [llms.txt](https://docs.livekit.io/llms.txt).