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.
/api/v1/agentsQuery parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Match name, description or tag. |
page | number | Page number. Default: |
pageSize | number | Up to 200. Default: |
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}}}
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.
/api/v1/agentsResponses
{"data": {"id": "44b1…","name": "Prescription follow-up","engine": "realtime","currentVersion": 1},"meta": {"requestId": "req_…"}}
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.
/api/v1/agents/{agentId}Path parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"id": "44b1…","name": "Prescription follow-up"},"meta": {"requestId": "req_…"}}
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.
/api/v1/agents/{agentId}Path parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"id": "44b1…","currentVersion": 8},"meta": {"requestId": "req_…"}}
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.
/api/v1/agents/{agentId}/toolsPath parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"tools": [{"id": "tool_9a1c…","name": "checkEligibility"}]},"meta": {"requestId": "req_…"}}
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.
/api/v1/agents/{agentId}/toolsPath parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"tools": [{"id": "tool_9a1c…","name": "checkEligibility"}]},"meta": {"requestId": "req_…"}}
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.
/api/v1/agents/{agentId}/voicePath parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"voiceId": "87edb04c…","name": "Mark","language": "en-US"},"meta": {"requestId": "req_…"}}
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.
/api/v1/agents/{agentId}/voicePath parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"voiceId": "87edb04c…","name": "Mark","language": "en-US"},"meta": {"requestId": "req_…"}}
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.
/api/v1/voicesQuery parameters
| Parameter | Type | Description |
|---|---|---|
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_…"}}
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.
/api/v1/voices/{voiceId}/previewPath parameters
| Parameter | Type | Description |
|---|---|---|
voiceIdrequired | string | Voice id. |
Responses
{"contentType": "audio/mpeg"}
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.
/api/v1/agents/{agentId}/versionsPath parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Query parameters
| Parameter | Type | Description |
|---|---|---|
limit | number | Up to 200. Default: |
offset | number | Skip this many. Default: |
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_…"}}
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.
/api/v1/agents/{agentId}/rollbackPath parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"version": 9},"meta": {"requestId": "req_…"}}
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.
/api/v1/agents/{agentId}Path parameters
| Parameter | Type | Description |
|---|---|---|
agentIdrequired | string | Agent id. |
Responses
{"data": {"deleted": true},"meta": {"requestId": "req_…"}}
curl -X DELETE "https://voice.evryhealth.com/api/v1/agents/{agentId}" \-H "Authorization: Bearer YOUR_API_KEY"