Skip to content

Agents & templates

An agent is an AgentDefinition: persona, structured objectives, guardrails, knowledge pack, tools, and an LLM routing chain. Definitions are drafts you edit freely; calls are only ever placed against published versions, immutable snapshots that pin everything.

POST /v1/agents returns 201 with "status": "draft". The important constraints, all enforced at the contract:

  • disclosure_config is mandatory and non-removable. The AI-disclosure opener is a compliance-floor control; there is no agent without one.
  • tools[] must be a subset of the platform tool registry: check_calendar, book_meeting, send_sms, record_survey_answer, confirm_shift, schedule_callback, record_optout, end_call, custom_webhook. Nothing else is a tool.

The registry is a configuration vocabulary, not a claim that every backing operation is live in every deployment. A configured live phone call can execute only check_calendar, book_meeting, schedule_callback, record_optout, and end_call. Calendar actions use the active direct Google Calendar connection for that tenant; Microsoft/Outlook, brokered calendar providers, browser sandbox sessions, and simulated test calls do not receive calendar actions. send_sms, custom_webhook, survey capture, and shift confirmation remain outside the live model surface. The API reports an unavailable dependency as 503 and an unbuilt operation as 501; see Errors.

  • llm_route is an LLM chain only. STT and TTS are platform-defaulted and not API-settable, so a body carrying stt_route or tts_route is rejected 422. Speech routing is an operations decision, not a per-agent field at v1.
  • Structured objectives[] and guardrails live inside the definition and version with it, because there is no separate flow resource.

Template library: inspect before instantiating

Section titled “Template library: inspect before instantiating”

GET /v1/templates lists the platform-owned, versioned template library, filterable by use_case, each entry carrying its outcome_type, tool_grants[], and the webhook_payload_schema an integrator building against that use case should expect. GET /v1/templates/{id} adds the full seed, objectives and scoring blocks included.

POST /v1/templates/{id}/instantiate (requires name and disclosure_config) copies the template into an ordinary draft agent stamped with seeded_from_template_id and seeded_from_template_version. It also copies tool_grants[] unchanged. For a browser sandbox or simulated test workflow, create the direct no-tool draft shown above: those transports never receive contact-bound actions. A template may use only the supported live-phone subset named above, and calendar grants additionally need the tenant’s active Google Calendar connection. Other grants remain configuration only and cannot execute in a live call.

The copy is not a live link: every field is editable, and later template versions never reach back into it. No tenant endpoint creates or edits a template, and there is no separate template runtime. Instantiating a draft or deprecated template refuses with template_not_published.

POST /v1/agents/{id}/publish snapshots the definition into an immutable AgentVersion (agv_…) that every subsequent call pins. Publish is blocked until the golden-transcript replay suite passes for this version, and failure returns 409 eval_gate_failed with the EvalRun reference in errors[]. Request the required run with POST /v1/agents/{id}/release-gate-evaluations; it seals the current draft and queues the built-in golden suite. The deployment’s release worker must process it before publish can succeed. The current scripted_stand_in mode uses sandboxed tools and is not a live-provider or carrier evaluation. Publish can also refuse when the version would pin nothing usable: compliance_profile_unresolved (no compliance profile and no tenant default) and knowledge_pack_version_unresolved (no compiled pack version to pin).

Drafts are never dialed: launching a campaign or placing a test call against an agent with no published version refuses with agent_not_published.

GET /v1/agents/{id}/versions lists the history. Once a campaign launches, its agent pin is immutable (agent_pin_immutable), so every call it placed carries the version pinned at launch, so the pin cannot be moved underneath that evidence. Per-call analysis on GET /v1/calls/{id} carries rubric_version pinning the AgentVersion whose rubric scored the call; re-publishing never restates past analyses.

The practical loop: edit the draft, request and wait for a passing scripted release check, publish it, and point new work at the new version, because old versions remain exactly what they were when they dialed. Use a test call after the version is published and before you attach it to a campaign.