Agents

Create, edit and version the thing that actually talks to people.

An agent is created from plain-language instructions, not from a prompt. The platform generates the prompt, versions it, and keeps the instructions as the thing a human edits — so an agent built through the API is the same object as one built in the product, editable in both.

`engine` names the product, never the vendor behind it: `realtime` is the managed engine, `pipeline` assembles your own transcription, language and speech models, and `speech-to-speech` runs a third-party realtime model with its own voice. Which models an engine runs on is configured in the product and is not part of this contract.

Every change is a version. A run, a call or an eval result names the version it was made against, which is what makes a result attributable months later.

List agents

Agents visible to the key's organization.

GET/api/v1/agents

Query parameters

ParameterTypeDescription
search
string

Match name, description or tag.

page
number

Page number.

Default: 1

pageSize
number

Up to 200.

Default: 50

Responses

{
"data": {
"agents": [
{
"id": "44b1…",
"name": "Prescription follow-up",
"instructions": "Call the pharmacy and confirm the prescription is ready.",
"engine": "realtime",
"modality": "voice",
"voice": {
"name": "Mark",
"language": "en-US"
},
"currentVersion": 7
}
]
},
"meta": {
"requestId": "req_…",
"pagination": {
"nextCursor": null,
"limit": 50
}
}
}
Request
curl -X GET "https://voice.evryhealth.com/api/v1/agents" \
-H "Authorization: Bearer YOUR_API_KEY"

Create an agent

Describe what the agent should do; the prompt is generated from it.

POST/api/v1/agents

Responses

{
"data": {
"id": "44b1…",
"name": "Prescription follow-up",
"engine": "realtime",
"currentVersion": 1
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X POST "https://voice.evryhealth.com/api/v1/agents" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Prescription follow-up",
"instructions": "Call the pharmacy, confirm the prescription is ready, and ask when it can be collected.",
"engine": "realtime",
"variables": [
{
"name": "patientName",
"description": "Who the prescription is for"
}
]
}'

Get an agent

One agent, as it stands now.

GET/api/v1/agents/{agentId}

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"id": "44b1…",
"name": "Prescription follow-up"
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}" \
-H "Authorization: Bearer YOUR_API_KEY"

Update an agent

Change any subset. Changing instructions regenerates the prompt as a new version.

PATCH/api/v1/agents/{agentId}

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"id": "44b1…",
"currentVersion": 8
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X PATCH "https://voice.evryhealth.com/api/v1/agents/{agentId}" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"instructions": "Confirm the prescription and ask when it can be collected."
}'

Tools on an agent

The tools this agent may call.

GET/api/v1/agents/{agentId}/tools

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"tools": [
{
"id": "tool_9a1c…",
"name": "checkEligibility"
}
]
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}/tools" \
-H "Authorization: Bearer YOUR_API_KEY"

Set an agent's tools

Replaces the whole list. It is one field on the agent, so adding tools one at a time would mean whichever request lost the race lost its tool. Every id is checked against what the key can reach — an agent cannot be given a tool from another tenant.

PUT/api/v1/agents/{agentId}/tools

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"tools": [
{
"id": "tool_9a1c…",
"name": "checkEligibility"
}
]
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X PUT "https://voice.evryhealth.com/api/v1/agents/{agentId}/tools" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"toolIds": [
"tool_9a1c…",
"tool_41bb…"
]
}'

Agent voice

The voice this agent speaks with.

GET/api/v1/agents/{agentId}/voice

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"voiceId": "87edb04c…",
"name": "Mark",
"language": "en-US"
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}/voice" \
-H "Authorization: Bearer YOUR_API_KEY"

Set an agent's voice

Pick a voice from `GET /api/v1/voices`. Only the managed and pipeline engines have a voice to set — a speech-to-speech engine's voice is part of the model it runs, and setting one there is refused rather than accepted and ignored.

PUT/api/v1/agents/{agentId}/voice

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"voiceId": "87edb04c…",
"name": "Mark",
"language": "en-US"
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X PUT "https://voice.evryhealth.com/api/v1/agents/{agentId}/voice" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"voiceId": "87edb04c…",
"language": "en-US"
}'

List voices

Voices an agent can speak with, each with a language and a sample to listen to — which is the only honest way to choose one.

GET/api/v1/voices

Query parameters

ParameterTypeDescription
language
string

BCP47 or a bare language code. `es` matches every Spanish voice.

Responses

{
"data": {
"voices": [
{
"id": "87edb04c…",
"name": "Mark",
"description": "Warm, measured, American English.",
"language": "en-US",
"previewUrl": "/api/v1/voices/87edb04c…/preview"
}
]
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X GET "https://voice.evryhealth.com/api/v1/voices" \
-H "Authorization: Bearer YOUR_API_KEY"

Voice sample

A spoken sample of one voice, as audio. Streamed through us rather than linked, so a voice picker never fetches from a host the customer has no relationship with.

GET/api/v1/voices/{voiceId}/preview

Path parameters

ParameterTypeDescription
voiceIdrequired
string

Voice id.

Responses

{
"contentType": "audio/mpeg"
}
Request
curl -X GET "https://voice.evryhealth.com/api/v1/voices/{voiceId}/preview" \
-H "Authorization: Bearer YOUR_API_KEY"

Version history

Every change: what changed, who changed it, and why.

GET/api/v1/agents/{agentId}/versions

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Query parameters

ParameterTypeDescription
limit
number

Up to 200.

Default: 50

offset
number

Skip this many.

Default: 0

Responses

{
"data": {
"versions": [
{
"versionNumber": 8,
"changeType": "prompt_updated",
"changedByName": "Maria Alvarez",
"changedAt": "2026-09-15T13:02:00.000Z",
"isCurrent": true
}
],
"currentVersion": 8,
"total": 8
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}/versions" \
-H "Authorization: Bearer YOUR_API_KEY"

Roll back

Return to an earlier version. The rollback is recorded as a new version rather than rewinding history, so what the agent was doing on any given day stays answerable.

POST/api/v1/agents/{agentId}/rollback

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"version": 9
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X POST "https://voice.evryhealth.com/api/v1/agents/{agentId}/rollback" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"version": 6,
"reason": "Version 7 asked for the date twice"
}'

Delete an agent

Remove an agent. Calls it already made are unaffected.

DELETE/api/v1/agents/{agentId}

Path parameters

ParameterTypeDescription
agentIdrequired
string

Agent id.

Responses

{
"data": {
"deleted": true
},
"meta": {
"requestId": "req_…"
}
}
Request
curl -X DELETE "https://voice.evryhealth.com/api/v1/agents/{agentId}" \
-H "Authorization: Bearer YOUR_API_KEY"