Skip to main content
An agent is the configuration that drives every ThunderPhone call — the product tier, the voice, the system prompt, the acknowledgement behavior, the tool integrations, and whether the agent is reachable from the web widget. Phone numbers assign an inbound and/or outbound agent; outbound calls and mic sessions can target an agent directly.

Endpoints

MethodPathDescription
GET/v1/agentsList agents
POST/v1/agentsCreate an agent
GET/v1/agents/{agent_id}Retrieve a single agent
PUT / PATCH/v1/agents/{agent_id}Replace / partially update
DELETE/v1/agents/{agent_id}Delete an agent
POST/v1/agents/{agent_id}/duplicateDuplicate an agent
POST/v1/agents/{agent_id}/transferCopy or move an agent to another org
GET/v1/agents/{agent_id}/versionsList prior configuration revisions
POST/v1/agents/prompt-language-checkDetect the language of a prompt
POST/v1/agents/translate-promptTranslate a prompt into another locale
POST/v1/agents/generate-acknowledgement-promptAuto-generate a Storm-mode acknowledgement prompt

Agent object

{
  "id": 12,
  "name": "Customer Support Agent",
  "prompt": "You are a helpful support agent for Acme Ops…",
  "voice": "en-US-James1",
  "product": "spark",
  "thinking_level": "base",
  "background_track": null,
  "acknowledgement_prompt_mode": "auto",
  "acknowledgement_prompt": "",
  "inbound_speak_order": "agent_first",
  "outbound_speak_order": "caller_first",
  "integrations": [],
  "widget_enabled": true,
  "created_at": "2026-04-20T18:24:10.113Z",
  "updated_at": "2026-04-20T18:24:10.113Z"
}
FieldTypeDescription
idintegerServer-assigned agent id
namestringHuman-readable name. 1–255 chars
promptstringThe system prompt that governs agent behavior
voicestringVoice id from GET /v1/voices — e.g. en-US-James1
productstringProduct tier. One of: spark, bolt, storm-base, storm-base-with-ack, storm-extra, storm-extra-with-ack
thinking_levelstringbase or extra. Derived from product for Storm tiers
background_trackstring | nullAmbient audio id to play during calls, or null for silence
acknowledgement_prompt_modestringauto (we generate the ack prompt) or manual (you supply it)
acknowledgement_promptstringUsed when acknowledgement_prompt_mode="manual". Storm-tier only
inbound_speak_orderstringWho talks first on inbound calls. agent_first or caller_first
outbound_speak_orderstringWho talks first on outbound calls
integrationsarrayLinked Integration objects
widget_enabledbooleanWhether the agent is reachable via the embeddable web widget
created_at, updated_attimestampISO 8601 UTC
The underlying Agent model also stores max_hold_seconds (per-agent hold timeout) and tools (inline function-tool schemas). These are written through create/update payloads and used by the call runtime, but they are not currently included in GET responses — use Integrations as the canonical location for tool config.

Product tiers at a glance

ProductLatencyReasoningAcknowledgement
sparkLowestBasic
boltLowImproved
storm-baseMediumStrong
storm-base-with-ackMediumStrongAutomatic filler while thinking
storm-extraHigherDeep
storm-extra-with-ackHigherDeepAutomatic filler while thinking
See the Storm launch notes for full latency/quality tradeoffs.

List agents

curl https://api.thunderphone.com/v1/agents \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
Returns an array of Agent objects, sorted by created_at descending.

Create an agent

curl -X POST https://api.thunderphone.com/v1/agents \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Customer Support Agent",
    "prompt": "You are a helpful support agent for Acme Ops…",
    "voice": "en-US-James1",
    "product": "spark",
    "widget_enabled": true
  }'
FieldTypeRequiredDescription
namestringyes1–255 chars
promptstringyesSystem prompt
voicestringyesVoice id from /v1/voices
productstringnoDefaults to spark
thinking_levelstringnoIgnored for Storm tiers (derived from product)
background_trackstring | nullno
acknowledgement_prompt_modestringnoauto or manual. Only meaningful for Storm-with-ack products
acknowledgement_promptstringnoRequired if acknowledgement_prompt_mode="manual"
inbound_speak_orderstringnoDefaults to agent_first
outbound_speak_orderstringnoDefaults to caller_first
max_hold_secondsinteger | nullnoPositive integer or null
toolsarraynoInline function-tool schemas
integration_idsarray of UUIDnoLink reusable integrations by id
widget_enabledbooleannoDefaults to true
Returns 201 Created with the new Agent object.

Retrieve an agent

curl https://api.thunderphone.com/v1/agents/12 \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
Returns 200 OK with an Agent object, or 404 if not found.

Update an agent

PATCH updates only the fields you include. PUT replaces the full object — you must send every required field.
curl -X PATCH https://api.thunderphone.com/v1/agents/12 \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "You are a refined support agent…"}'

Optimistic concurrency

To safely make edits from a UI, include if_updated_at with the last updated_at you observed:
{
  "prompt": "Newer prompt",
  "if_updated_at": "2026-04-20T18:24:10.113Z"
}
If the server-side updated_at differs, the API returns 409 Conflict with code: "conflict" so you can refresh and retry. Returns 200 OK with the updated Agent object.

Delete an agent

curl -X DELETE https://api.thunderphone.com/v1/agents/12 \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
Returns 204 No Content. Phone numbers that reference the deleted agent have their inbound/outbound assignment cleared.

Duplicate an agent

Creates a new agent with the same core configuration in the same org. The duplicate copies: name (overridable), prompt, voice, product, thinking level, background track, acknowledgement prompt mode and content, widget enabled, and linked integrations. Speak-order, max_hold_seconds, and inline tools are not copied — if you rely on those, re-apply them on the duplicate via PATCH.
curl -X POST https://api.thunderphone.com/v1/agents/12/duplicate \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Customer Support Agent (clone)"}'
FieldTypeRequiredDescription
namestringnoDefaults to "<original name> (copy)"
Returns 201 Created with the new Agent object.

Transfer an agent to another org

Copy or move an agent to a different organization you’re also a member of. admin+ role is required on the target org for both modes, and for the source org when mode="move".
curl -X POST https://api.thunderphone.com/v1/agents/12/transfer \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_org_id": 77,
    "mode": "copy"
  }'
FieldTypeRequiredDescription
target_org_idintegeryesMust differ from the source org id
modestringyescopy (keep source intact) or move (delete source after copy)
namestringnoOverride the new agent’s name
Returns 201 Created for copy / 200 OK for move:
{
  "mode": "copy",
  "target_org_id": 77,
  "agent": { /* Agent object in the target org */ }
}
Linked integrations are not transferred. The new agent starts with an empty integration list.

Version history

Every PUT, PATCH, or create operation records an AgentConfigVersion snapshot so you can see (and eventually restore) prior configurations. This endpoint lists recent revisions:
curl 'https://api.thunderphone.com/v1/agents/12/versions?limit=20' \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
Query paramDefaultDescription
limit20Max results (1–100)
Response:
{
  "count": 3,
  "results": [
    {
      "id": 501,
      "revision": 3,
      "created_by": "jane@example.com",
      "created_at": "2026-04-20T18:24:10.113Z",
      "snapshot": { /* Full Agent object at this revision */ },
      "changed_fields": ["prompt", "voice"]
    }
  ]
}

Prompt helpers

These three endpoints are convenience wrappers that call the same underlying models we use in the dashboard. All three take and return JSON; none change any persisted resource.

Detect prompt language

curl -X POST https://api.thunderphone.com/v1/agents/prompt-language-check \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Hola, gracias por llamar..."}'
Response
{
  "detected_language_code": "es",
  "detected_language_name": "Spanish",
  "mismatch": true,
  "provider": "gemini"
}

Translate prompt

curl -X POST https://api.thunderphone.com/v1/agents/translate-prompt \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Hola, gracias por llamar…",
    "target_locale": "en-US"
  }'
Response
{
  "translated_prompt": "Hello, thank you for calling…",
  "source_language_code": "es",
  "source_language_name": "Spanish",
  "provider": "gemini",
  "used_fallback": false
}

Generate acknowledgement prompt

Produces a short “filler while thinking” phrase appropriate for Storm-with-ack products.
curl -X POST https://api.thunderphone.com/v1/agents/generate-acknowledgement-prompt \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "You are a friendly receptionist for a dental office.",
    "target_locale": "en-US"
  }'
Response
{
  "acknowledgement_prompt": "Sure, let me take a quick look…",
  "provider": "gemini",
  "used_fallback": false
}

Voices

List the supported voice ids:
curl https://api.thunderphone.com/v1/voices \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
Returns an array of {id, name, locale, tier, sample_url} objects. The id is what you set on an agent’s voice field.

Phone Numbers

Assign agents to inbound/outbound directions on phone numbers.

Integrations

Reusable HTTP integrations an agent can call mid-conversation.

Outbound Calls

Trigger an outbound call using a configured agent.

Calls

Inspect call history once your agent is running.