Agents
An agent is a person who takes calls in the agent widget. Agents are grouped into teams, and IVR flows route callers to them. See Agents & routing for the concepts.
All endpoints accept a tenant API key or a console session.
The agent object
Section titled “The agent object”| Field | Type | Description |
|---|---|---|
id |
UUID | Agent ID. |
tenant_id |
UUID | Owning tenant. |
sip_username |
string | The agent’s username, unique in the tenant. Typically your CRM user ID. |
display_name |
string | Name shown to supervisors and in the console. Left out when empty. |
available_for_calls |
boolean | Your backend’s availability flag (your “Away” / “Break” button). Tring rings an agent only when they’re connected and available. |
created_at |
timestamp | When the agent was created. |
status |
string | Live status. Only in the list response. See below. |
status combines whether the agent is connected with available_for_calls:
status |
Meaning |
|---|---|
online |
Connected and available. Can be rung. |
on_call |
Connected and busy on a call. |
away |
Connected, but available_for_calls is false. |
offline |
Not connected. |
unknown |
Only in the legacy SIP mode: Tring couldn’t reach FreeSWITCH to check. |
POST /v1/agents
Section titled “POST /v1/agents”Create an agent.
Auth: API key or console session.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
sip_username |
string | yes | Unique within the tenant. Letters, digits and . _ @ + -, up to 64 characters. Use your own user ID so you can address the agent by it. |
display_name |
string | no | Human-readable name. |
curl -sS -X POST "$TRING_URL/v1/agents" \ -H "Authorization: Bearer $TRING_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"sip_username":"agent-1042","display_name":"Asha Example"}'Response 201 Created
{ "id": "9a3e5d10-0000-4000-8000-00000000c001", "tenant_id": "00000000-0000-4000-8000-000000000001", "sip_username": "agent-1042", "display_name": "Asha Example", "available_for_calls": true, "created_at": "2026-10-16T09:41:07.512843+05:30"}Agents authenticate with an agent token, not SIP credentials. Tring still generates and stores a SIP password for the legacy sip agent transport, but never returns it.
A new agent isn’t in any team yet. Add it with POST /v1/teams/{name}/agents.
Errors
| Status | error |
|---|---|
400 |
invalid JSON body |
400 |
sip_username required |
400 |
sip_username may only contain letters, digits and . _ @ + - (max 64) |
409 |
sip_username already exists for this tenant |
500 |
generate password, create agent failed |
GET /v1/agents
Section titled “GET /v1/agents”List all agents in the tenant, newest first, with their live status. Not paginated.
Auth: API key or console session.
curl -sS "$TRING_URL/v1/agents" \ -H "Authorization: Bearer $TRING_API_KEY"Response 200 OK
[ { "id": "9a3e5d10-0000-4000-8000-00000000c001", "tenant_id": "00000000-0000-4000-8000-000000000001", "sip_username": "agent-1042", "display_name": "Asha Example", "available_for_calls": true, "created_at": "2026-10-16T09:41:07.512843+05:30", "status": "online" }, { "id": "9a3e5d10-0000-4000-8000-00000000c002", "tenant_id": "00000000-0000-4000-8000-000000000001", "sip_username": "agent-1043", "available_for_calls": false, "created_at": "2026-10-15T18:20:00.000000+05:30", "status": "away" }]Errors
| Status | error |
|---|---|
500 |
query failed |
GET /v1/agents/{id}
Section titled “GET /v1/agents/{id}”Get one agent. This response has no status field: use the list, or the dashboard stream, for live status.
Auth: API key or console session.
| Path param | Description |
|---|---|
id |
Agent UUID or sip_username. |
curl -sS "$TRING_URL/v1/agents/agent-1042" \ -H "Authorization: Bearer $TRING_API_KEY"Response 200 OK
{ "id": "9a3e5d10-0000-4000-8000-00000000c001", "tenant_id": "00000000-0000-4000-8000-000000000001", "sip_username": "agent-1042", "display_name": "Asha Example", "available_for_calls": true, "created_at": "2026-10-16T09:41:07.512843+05:30"}Errors
| Status | error |
|---|---|
404 |
agent not found |
500 |
query failed |
POST /v1/agents/{id}/availability
Section titled “POST /v1/agents/{id}/availability”Mark an agent available or unavailable for calls. Wire this to the Away / Break button in your own app, calling from your backend. An unavailable agent stays connected, but Tring stops ringing them.
Auth: API key or console session.
| Path param | Description |
|---|---|
id |
Agent UUID or sip_username. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
available |
boolean | yes | true to take calls, false to stop. A missing field counts as false. |
curl -sS -X POST "$TRING_URL/v1/agents/agent-1042/availability" \ -H "Authorization: Bearer $TRING_API_KEY" \ -H 'Content-Type: application/json' \ -d '{"available":false}'Response 200 OK with the updated agent (same shape as GET /v1/agents/{id}).
Each change also sends an agent.status event on the dashboard stream, with this data:
{ "agent_id": "9a3e5d10-0000-4000-8000-00000000c001", "sip_username": "agent-1042", "available_for_calls": false}Errors
| Status | error |
|---|---|
400 |
invalid JSON body |
404 |
agent not found |
500 |
query failed, update failed |
GET /v1/agents/{id}/token
Section titled “GET /v1/agents/{id}/token”Mint a short-lived agent token for the agent widget. Your backend calls this after checking that the signed-in user really is this agent, and returns the response to the agent’s browser. The browser never sees your API key.
Auth: API key or console session.
| Path param | Description |
|---|---|
id |
Agent UUID or sip_username. |
curl -sS "$TRING_URL/v1/agents/agent-1042/token" \ -H "Authorization: Bearer $TRING_API_KEY"Response 200 OK
{ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.example.signature", "expires_at": "2026-10-16T09:46:07.512843+05:30", "gateway_url": "https://gw.example.com", "ice_servers": [ { "urls": "stun:stun.example.com:3478" } ]}| Field | Description |
|---|---|
token |
The agent token (JWT). Valid for 5 minutes. |
expires_at |
When the token expires. |
gateway_url |
Media gateway URL the widget connects to. Left out if TRING_GATEWAY_PUBLIC_URL isn’t set. |
ice_servers |
STUN/TURN servers in RTCIceServer format. Left out if none are configured. |
Pass this response through unchanged from the endpoint your widget’s data-token-url points at, and the widget needs no other configuration. The token is also accepted by the agent’s own call-control routes (/v1/sdk/*). See Authentication.
Errors
| Status | error |
|---|---|
404 |
agent not found |
500 |
query failed, issue token |