For the complete documentation index, see llms.txt. Any page on this site can be fetched as Markdown by appending .md to its URL.

Voice agentsAgent versions

Create a draft version

POST
/v1/agent-media/agents/{agentId}/versions/{version}

Save a new draft at the version number in the path. You choose the number; Tandem never assigns one. The agent must already exist, and the number must not — this endpoint never overwrites, so use PUT to revise a draft.

A draft is checked for shape only. Every bound the published configuration enforces is enforced here — a field you send must be valid, and a system prompt over 100,000 bytes on the wire is rejected — but the configuration may be incomplete: systemPrompt and slots are optional on a draft so you can save before you have written the prompt or picked a model. The checks a draft does not run are the ones that need the rest of the platform: whether {{org.*}} and {{secrets.*}} references resolve, whether a secret sits somewhere it is allowed to, whether the ElevenLabs voice you picked is connected, and whether an agent tool points at something callable. Those run at publish, which is the first moment the configuration can take a call. A draft that saves cleanly can still fail to publish.

An agent may hold at most 20 versions. Delete one to make room.

Storing a {{secrets.*}} reference requires an organization admin, the same rule the configuration PUT has always carried.

Authorization

bearerAuth
AuthorizationBearer <token>

A Tandem bearer token. Requests are scoped to the organization the token belongs to; no organization header is required.

In: header

Path Parameters

agentId*string

The agent's unique ID.

version*string

The version number: <major>.<minor>, two non-negative integers with no leading zeros and at most nine digits each — 0.1, 1.0, 2.13. You choose it. Anything else is rejected with invalid_version, because the number is part of the version's storage key.

Match^(0|[1-9]\d{0,8})\.(0|[1-9]\d{0,8})$

Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

The body a version create or update takes: the configuration, plus an optional release note.

version comes from the path, never the body. name and sourceTemplateId are not part of a version — send them and they are dropped rather than rejected, so a configuration read back off an agent can be posted here as-is. Change the name with PUT /v1/agent-media/agents/{agentId}.

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://example.com/v1/agent-media/agents/string/versions/string" \  -H "Content-Type: application/json" \  -d '{}'
{  "version": {    "version": "string",    "description": "string",    "publishedAt": "2019-08-24T14:15:22Z",    "createdBy": "string",    "updatedBy": "string",    "backfilledAt": "2019-08-24T14:15:22Z",    "createdAt": "2019-08-24T14:15:22Z",    "updatedAt": "2019-08-24T14:15:22Z",    "systemPrompt": "string",    "greeting": "string",    "interruptable": true,    "channels": [      "voice",      "chat"    ],    "slots": {      "llm": {        "model": "string",        "settings": {          "maxTokens": 1,          "temperature": 0,          "reasoning": {            "enabled": false,            "budgetTokens": 1024          }        }      },      "stt": {        "provider": "string",        "settings": {          "language": "string"        }      },      "tts": {        "voiceProvider": "string",        "settings": {          "language": "string",          "voiceId": "string",          "engine": "string",          "polly": {            "rate": "string",            "volume": "string"          },          "elevenlabs": {            "speed": 0.7,            "stability": 0,            "similarityBoost": 0,            "style": 0,            "useSpeakerBoost": true,            "textNormalization": "auto",            "pronunciationDictionaries": [              {                "id": "string",                "versionId": "string"              }            ]          }        }      },      "additionalVoices": [        {          "voiceProvider": "string",          "settings": {            "language": "string",            "voiceId": "string",            "engine": "string",            "polly": {              "rate": "string",              "volume": "string"            },            "elevenlabs": {              "speed": 0.7,              "stability": 0,              "similarityBoost": 0,              "style": 0,              "useSpeakerBoost": true,              "textNormalization": "auto",              "pronunciationDictionaries": [                {                  "id": "string",                  "versionId": "string"                }              ]            }          }        }      ]    },    "greetingParts": [      {        "language": "string",        "text": "string"      }    ],    "variables": [],    "dispositions": [],    "builtinTools": {      "transferToExternal": {        "enabled": false,        "destinations": []      },      "transferToVoiceAgent": {        "enabled": false,        "contextCarryover": "none",        "destinations": []      },      "captureDtmf": {        "enabled": false,        "maxDigits": 16,        "terminator": "#",        "timeoutMs": 10000,        "interDigitTimeoutMs": 3000,        "interruptsSpeech": true      },      "recordingControl": {        "enabled": false      },      "currentTime": {        "enabled": false,        "timezone": "America/New_York"      },      "setWorkflowVariable": {        "enabled": false,        "variables": []      }    },    "dtmf": {      "enabled": false,      "interDigitGapMs": 1500,      "terminator": "#",      "maxDigits": 32,      "interruptsSpeech": true    },    "thinkingCue": {      "kind": "none"    },    "vad": {      "silenceMs": 200,      "threshold": 0.7,      "startMs": 200,      "minVolume": 0.6,      "endOfTurnGraceMs": 600,      "bargeInMinWords": 1    },    "turnDetection": {      "mode": "silence",      "smartStopMs": 3000,      "preSpeechMs": 500,      "maxDurationSecs": 8    },    "memory": {      "depth": "none",      "customizeGreeting": false    },    "safety": {      "redactPii": true,      "steeringRules": [        "string"      ]    },    "skills": {      "builtins": [],      "custom": []    },    "analysis": {      "enabled": false,      "builtins": {        "sentiment": {          "enabled": false,          "prompt": "string"        },        "outcome": {          "enabled": false,          "prompt": "string"        },        "summary": {          "enabled": false,          "prompt": "string"        }      },      "fields": []    },    "retention": {      "transcripts": true    },    "idle": {      "enabled": false,      "timeoutMs": 10000,      "action": "reprompt",      "prompt": "string",      "maxReprompts": 2,      "onExhausted": "endCall",      "disposition": "string"    },    "limits": {      "maxCallDurationMs": 60000,      "warnBeforeEndMs": 5000,      "warnPrompt": "string"    },    "reliability": {      "maxConsecutiveTurnFailures": 1,      "toolTimeoutMs": 1000,      "steeringJudgeTimeoutMs": 500,      "handoffMaxHistoryMessages": 1,      "modelRetryMaxAttempts": 1,      "modelRetryInitialDelayMs": 100,      "modelRetryMaxDelayMs": 100    },    "conversation": {      "strategy": "slidingWindow",      "windowSize": 10,      "summaryRatio": 0.1,      "preserveRecentMessages": 2,      "pinFirst": 1,      "proactiveCompressionThreshold": 0.3    },    "vocabulary": {      "terms": []    },    "dataCollection": {      "fields": [        {          "key": "string",          "label": "string",          "kind": "full_name",          "required": false,          "prompt": ""        }      ]    },    "tools": [],    "knowledge": {      "kbId": "string",      "maxResults": 4,      "minScore": 0    }  }}
{  "error": "string",  "message": "string",  "limit": 0,  "length": 0,  "reason": "string"}
{  "error": "string",  "message": "string",  "limit": 0,  "length": 0,  "reason": "string"}
{  "error": "string",  "message": "string",  "limit": 0,  "length": 0,  "reason": "string"}
{  "error": "string",  "message": "string",  "limit": 0,  "length": 0,  "reason": "string"}