Build an agent
Agents and models
Create or duplicate
POST/v1/agents creates an agent from scratch: a name, a gender and a language are enough. For a variant of an agent that already works (another club, another language, a test version), duplicate it instead: the copy keeps the call flow, the prompts, the settings and the assigned webhook.
curl -X POST "https://api.callshift.ai/v1/agents/$AGENT_ID/duplicate" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# { "id": "7c9e6679-7425-40de-944b-e07fc1f90ae7" }
curl -X PATCH "https://api.callshift.ai/v1/agents/7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-H "Authorization: Bearer $CALLSHIFT_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Alice (Spanish)", "language": "es" }'Settings
| Field | Values | Default |
|---|---|---|
name | 1 to 50 characters | required |
gender | FEMALE, MALE | required |
language | fr, en, nl, pt, es | required |
provider, model | See Choose a model | google, gemini-live-3.1-flash |
voiceId | A voice of the model's family, as shown in the dashboard's voice selector. Write-only: GET does not return it. | The family's default voice |
temperature | 0 to 2 | |
maxTokens | 1 to 10000 | |
silenceTimeoutSeconds | 5 to 120: the agent hangs up after this much silence from the caller | 25 |
maxDurationSeconds | 60 to 3600: the call then ends with max-duration-exceeded | 420 |
minEndpointingDelay | 0.3 to 2.5 seconds the agent waits after the caller stops speaking. Pipeline models only. | Platform default |
backgroundSound | office_ambience, city_ambience, forest_ambience, crowded_room, keyboard_typing, keyboard_typing2, hold_music, gym_ambience, or null | None |
backgroundSoundVolume | 0 to 1 | 0.2 |
summaryPrompt, evaluationPrompt, informationToCollect | See Call analysis | |
diagram | See Call flow | |
entityId, entityExternalId | See Entities | Shared |
Choose a model
Two families of models drive an agent.
| Family | Models (provider) | When to choose it |
|---|---|---|
| Speech-to-speech (realtime) | gemini-3.8-live, gemini-live-3.1-flash (google) · gpt-realtime-2.1-mini, gpt-live-1 (openai) · grok-voice-3.0 (xai) | The model hears and speaks directly: the most natural turn-taking and the shortest replies in time. |
| Pipeline | gpt-4o-mini, gpt-4o, gpt-4.1-mini, gpt-5-mini, gpt-5.4-mini (openai) | Speech-to-text, a language model, then text-to-speech: a wider choice of voices, and more reliable on dictated emails and numbers. minEndpointingDelay applies. |
Send provider and model from this list, and read the agent back with GET/v1/agents/{agentId} to confirm. To compare the two families on cost and latency, use the speech-to-speech vs pipeline simulator.
Update an agent safely
PATCH/v1/agents/{agentId} replaces each field you send as a whole, and leaves the others alone. The diagram is one field: read the agent, change the diagram, and send it back complete.
const api = (path, init = {}) =>
fetch(`https://api.callshift.ai${path}`, {
...init,
headers: {
Authorization: `Bearer ${process.env.CALLSHIFT_API_KEY}`,
"Content-Type": "application/json",
},
}).then((r) => r.json());
const agent = await api(`/v1/agents/${agentId}`);
const start = agent.diagram.nodes.find((n) => n.type === "startCall");
start.data.welcomeMessage =
"Hello, this is Alice, the AI assistant of Club Lyon Part-Dieu. How can I help?";
await api(`/v1/agents/${agentId}`, {
method: "PATCH",
body: JSON.stringify({ diagram: agent.diagram }),
});import os
import requests
API = "https://api.callshift.ai"
H = {"Authorization": f"Bearer {os.environ['CALLSHIFT_API_KEY']}"}
agent = requests.get(f"{API}/v1/agents/{agent_id}", headers=H).json()
start = next(n for n in agent["diagram"]["nodes"] if n["type"] == "startCall")
start["data"]["welcomeMessage"] = (
"Hello, this is Alice, the AI assistant of Club Lyon Part-Dieu. How can I help?"
)
requests.patch(f"{API}/v1/agents/{agent_id}", headers=H, json={"diagram": agent["diagram"]})Changes are live on the next call, and an agent has no version history. Duplicate an agent before a large change to keep the previous version, and for a staging copy, prefix its name ([STAGING] Alice) and assign your numbers to the production agent only.
Delete an agent
DELETE/v1/agents/{agentId} removes the agent and releases the numbers assigned to it. Its past calls stay readable.
