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.
Tags label agents and are not versioned. At most one of Production, Staging and Development marks the agent's environment; the rest are free-form, up to 20 per agent, 40 characters each, without commas. Tags that differ only in case are the same tag.
List agents#
Agents visible to the key's organization.
/api/v1/agentsQuery parameters
searchstring- Match name, description or tag.
tagstring- Only agents carrying this tag. Comma-separate, or repeat, to match any of several.
pagenumber- Page number.
- Default
1 pageSizenumber- Up to 200.
- Default
50
Responses
A page of agents.
curl -X GET "https://voice.evryhealth.com/api/v1/agents" \-H "Authorization: Bearer YOUR_API_KEY"
{"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}}}
Create an agent#
Describe what the agent should do; the prompt is generated from it before the agent is saved, the same way the product writes one, and the agent starts at version 1. Writing the prompt takes a few seconds to a minute. If it cannot be written the request fails with 503 and no agent is created; retrying is safe, and with an Idempotency-Key it cannot create the agent twice.
/api/v1/agentsBody
application/jsonname- string
- required
description- string
instructions- string
- required
engine- realtime | pipeline | speech-to-speech
modality- voice | text | both
variables- { name, description }[]
tags- string[]
isOrgShared- boolean
Responses
The created agent.
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"}]}'
{"data": {"id": "44b1…","name": "Prescription follow-up","engine": "realtime","currentVersion": 1},"meta": {"requestId": "req_…"}}
Get an agent#
One agent, as it stands now.
/api/v1/agents/{agentId}Path parameters
agentIdstringrequired- Agent id.
Responses
The agent.
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}" \-H "Authorization: Bearer YOUR_API_KEY"
{"data": {"id": "44b1…","name": "Prescription follow-up"},"meta": {"requestId": "req_…"}}
Update an agent#
Change any subset. Every change to the name, description, instructions, variables or engine is saved as a new version, which rollback can return to. Changing the instructions or the variables writes the prompt again from them, replacing any edits made to it in the product. `modality`, `isOrgShared` and `tags` are not versioned. If the prompt cannot be written the request fails with 503 and the agent is unchanged.
/api/v1/agents/{agentId}Path parameters
agentIdstringrequired- Agent id.
Body
application/jsonname- string
description- string
instructions- string
engine- realtime | pipeline | speech-to-speech
modality- voice | text | both
variables- { name, description }[]
tags- string[]
isOrgShared- boolean
Responses
The updated agent.
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."}'
{"data": {"id": "44b1…","currentVersion": 8},"meta": {"requestId": "req_…"}}
Tools on an agent#
The tools this agent may call.
/api/v1/agents/{agentId}/toolsPath parameters
agentIdstringrequired- Agent id.
Responses
The attached tools.
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}/tools" \-H "Authorization: Bearer YOUR_API_KEY"
{"data": {"tools": [{"id": "tool_9a1c…","name": "checkEligibility"}]},"meta": {"requestId": "req_…"}}
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
agentIdstringrequired- Agent id.
Body
application/jsontoolIds- string[]
- required
Responses
The attached tools.
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…"]}'
{"data": {"tools": [{"id": "tool_9a1c…","name": "checkEligibility"}]},"meta": {"requestId": "req_…"}}
Agent voice#
The voice this agent speaks with.
/api/v1/agents/{agentId}/voicePath parameters
agentIdstringrequired- Agent id.
Responses
The voice.
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}/voice" \-H "Authorization: Bearer YOUR_API_KEY"
{"data": {"voiceId": "87edb04c…","name": "Mark","language": "en-US"},"meta": {"requestId": "req_…"}}
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
agentIdstringrequired- Agent id.
Body
application/jsonvoiceId- string
- required
language- string (BCP47)
Responses
The voice now set.
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"}'
{"data": {"voiceId": "87edb04c…","name": "Mark","language": "en-US"},"meta": {"requestId": "req_…"}}
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
languagestring- BCP47 or a bare language code. `es` matches every Spanish voice.
Responses
The voices.
curl -X GET "https://voice.evryhealth.com/api/v1/voices" \-H "Authorization: Bearer YOUR_API_KEY"
{"data": {"voices": [{"id": "87edb04c…","name": "Mark","description": "Warm, measured, American English.","language": "en-US","previewUrl": "/api/v1/voices/87edb04c…/preview"}]},"meta": {"requestId": "req_…"}}
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
voiceIdstringrequired- Voice id.
Responses
Audio (audio/mpeg).
curl -X GET "https://voice.evryhealth.com/api/v1/voices/{voiceId}/preview" \-H "Authorization: Bearer YOUR_API_KEY"
{"contentType": "audio/mpeg"}
Version history#
Every change: what changed, who changed it, and why.
/api/v1/agents/{agentId}/versionsPath parameters
agentIdstringrequired- Agent id.
Query parameters
limitnumber- Up to 200.
- Default
50 offsetnumber- Skip this many.
- Default
0
Responses
The history.
curl -X GET "https://voice.evryhealth.com/api/v1/agents/{agentId}/versions" \-H "Authorization: Bearer YOUR_API_KEY"
{"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_…"}}
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
agentIdstringrequired- Agent id.
Body
application/jsonversion- number
- required
reason- string
Responses
The new version number.
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"}'
{"data": {"version": 9},"meta": {"requestId": "req_…"}}
Delete an agent#
Remove an agent. Calls it already made are unaffected.
/api/v1/agents/{agentId}Path parameters
agentIdstringrequired- Agent id.
Responses
Deleted.
curl -X DELETE "https://voice.evryhealth.com/api/v1/agents/{agentId}" \-H "Authorization: Bearer YOUR_API_KEY"
{"data": {"deleted": true},"meta": {"requestId": "req_…"}}