Write to draft
Upsert the open draft on this branch. If no draft is open, one is created automatically. The request body is an agent config partial in the same camelCase shape as GET /agent/{id} (globalPrompt, firstMessage, synthesizer, language, voiceDetectionConfig, smartTurnConfig, …) and must contain at least one recognized field; the server merges it into the existing draft and returns the resulting draft as a revision-shaped snapshot.
Send native JSON types, not stringified values. Arrays (language.supported: ["en"]), booleans (language.switching.isEnabled: false), and objects (timezone: {"label": "(GMT+5:30) Asia/Kolkata", "offset": 330}) must be sent as real JSON. Passing "[\"en\"]", "false", or "Asia/Kolkata" instead is refused with a Zod-style error naming the offending path and the received type (e.g. Invalid config: language.supported: Expected array, received string). This is the single most common integration bug on this endpoint.
Post-call-analytics limits. When the payload includes postCallAnalyticsConfig.dispositionMetrics, two aggregate limits are enforced with 400 errors:
- Combined prompt length. The total of every
dispositionMetricPromptacross all metrics must be ≤ 50,000 characters. Error:The combined disposition metric prompts can be at most 50000 characters. - Enum-choice cap. Each
dispositionMetricType: ENUMmetric may have at most 20choices. Error:Each enum metric can have at most 20 choices. Ones already over the limit can stay as they are, but can't grow any further. Remove the extra choices to save.
Both limits are grandfathered: an agent already over either limit can still save as long as the change does not make it worse (the combined prompt length does not grow, and no over-limit enum grows or gains new choices). No cap on the number of metrics or on a single prompt’s length.
Publish the draft with POST /agent/{id}/branches/{branchId}/draft/publish to make the changes live. The draft PUT alone does not affect running calls.
Authentication
API key from the console ApiKey collection, sent as Bearer token. Also accepts session cookies for browser-based auth.
Path parameters
Request
Optimistic-concurrency control. The draftRevision the client's edit was based on. When present, the server runs a field-level conflict check and rejects with 409 DraftConflictError if the same field was changed by another edit since. Omit for last-write-wins semantics (which is also how a client force-overwrites after a 409). Referencing a non-existent base revision returns 409 { errors: ["base_revision_unavailable"] }.
Top-level system prompt shown to the agent every turn.
LLM model powering the agent. See CreateAgentRequest.slmModel for org-level access notes.
Agent timezone applied to date/time interpretation in prompts, tool calls, and analytics bucketing. Object with a label (IANA-style label) and an offset (UTC offset in minutes). Sending a bare string is refused with Invalid config: timezone: Expected object, received string.
Knowledge base attached to the agent for retrieval-augmented responses.
TTS (voice) configuration. Same shape as CreateAgentRequest.synthesizer.
Language configuration. Same shape as CreateAgentRequest.language.
Pre-call API webhook config. Same shape as CreateAgentRequest.preCallAPI.
Response
An AgentVersion document. Represents either a committed revision (status: published, with branch + revisionNumber) or an in-progress draft revision (status: draft, with draftId + draftRevision). Fields that do not apply to a given row are null.