Calls
Trigger outbound voice calls with patient lineage, goal context, and end-to-end traceability in the world model.
The outbound call endpoint lets you place a voice call from a workspace phone number to a patient. Every call is linked to a patient entity and a reason, so the platform tracks who requested the call, why, and what happened - from the moment you make the API request through to the call outcome.
You only need an API key. No triggers, campaigns, or scheduling infrastructure required.
When to use this vs triggers. This endpoint is for on-demand calls - a CRM event fires, a care coordinator clicks a button, or your backend decides a patient needs a callback right now. For recurring or event-driven outreach (appointment reminders every 48 hours, lab result notifications), use Triggers instead - they handle scheduling, retry, and business-hours windows automatically.
Quick Start
curl -X POST https://api.platform.amigo.ai/v1/{workspace_id}/calls/outbound \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_to": "+18005551234",
"use_case_id": "cccccccc-0000-0000-0000-000000000001",
"patient_entity_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"reason": "lab_results"
}'The response includes a call_sid for tracking and an event_id pointing to the world model event:
{
"call_sid": "CA1234567890abcdef",
"status": "queued",
"phone_from": "+12125559876",
"setup_id": null,
"event_id": "f9e8d7c6-b5a4-3210-fedc-ba0987654321"
}Endpoint
POST /v1/{workspace_id}/calls/outbound
Required Fields
phone_to
string
Destination phone number in E.164 format (e.g. +18005551234). Max 16 characters.
use_case_id
string (UUID)
Use case identifier. The platform selects the optimal outbound phone number bound to that use case - this is the sole caller-ID resolution path.
patient_entity_id
string (UUID)
The patient this call is about. Must be an existing person entity in your workspace. Required if patient_canonical_id is not provided.
patient_canonical_id
string
The world model canonical ID for the patient, of the form source:resource_type:id (e.g. charmhealth:Patient:67890). Required if patient_entity_id is not provided.
reason
string
Why the call is being made. 1-256 characters. Examples: appointment_reminder, follow_up, lab_results, billing, care_plan_review.
patient_entity_id and patient_canonical_id are mutually exclusive. Provide exactly one. Use patient_entity_id when you have the workspace entity UUID, or patient_canonical_id to reference the patient by world model canonical ID (source:resource_type:id).
Optional Fields
service_id
string (UUID)
Which voice agent service to use. If omitted, the workspace default is used. Non-UUID values are rejected with a 422 validation error.
system_prompt
string
Override the agent's system prompt for this call. Max 10,000 characters.
goal
string
What the call should accomplish. This is injected into the agent's context so it knows the objective before the patient answers. Max 2,000 characters.
tags
array of strings
Classification tags for filtering and analytics (e.g. ["scheduling", "q2_campaign"]). Max 10 items, each max 64 characters.
metadata
object
Arbitrary key-value pairs for correlating with external systems. Max 20 entries, keys max 64 characters, values max 256 characters.
derived_from_call_sid
string
If this call is a callback from a prior conversation, pass the original call_sid here. Creates an explicit lineage chain between calls. Max 64 characters.
idempotency_key
string
Pass the same key on retries to prevent duplicate calls. Auto-generated if omitted. Max 128 characters.
outbound_task_entity_id
string (UUID)
Link to an existing outbound task entity for completion feedback. Non-UUID values are rejected with a 422 validation error.
Response (201 Created)
call_sid
string
Unique call identifier. Use this to look up call status and intelligence.
status
string
Initial call status - typically queued.
phone_from
string or null
The resolved caller ID - the outbound number the platform selected for the use case.
setup_id
string (UUID) or null
Setup identifier for the selected number.
event_id
string (UUID) or null
The world model event ID for the outbound.initiated event. Use this for lineage queries.
How It Works
When you create an outbound call, the platform handles the full lifecycle automatically:
Validation - The platform verifies the patient entity exists, resolves the caller ID, and queues the call with the downstream voice carrier.
Pre-warming - While the phone rings (typically 5-15 seconds), the agent loads the patient's full world model context, generates a greeting, and pre-renders the audio. This means zero cold-start delay when the patient answers.
Connection - When the patient picks up, the agent joins the call immediately with the pre-generated greeting. The patient hears the agent speak within ~1 second of answering.
Conversation - The call proceeds exactly like an inbound call. The agent has full access to tools, clinical context, and the conversation state machine.
Completion - Call outcomes, intelligence, and analytics are computed and available via the calls list, call detail, and trace analysis endpoints.
The status field in the response starts as queued and progresses through ringing → in-progress → completed (or failed/no-answer/busy). Use the call detail endpoint with the returned call_sid to check status and retrieve intelligence after the call.
How the Agent Uses Your Context
When you provide a goal, the platform appends it to the agent's system prompt before the call connects. The agent reads it during the pre-warming phase (while the phone is ringing) so it knows the objective by the time the patient answers.
The patient_entity_id also drives context loading. During pre-warming, the agent reads the patient's world model projection - demographics, active conditions, medications, upcoming appointments, and prior interaction history. The agent starts the call with full patient knowledge without needing to "look up" anything.
patient_entity_id
Full patient context from the world model (demographics, clinical, history)
goal
Injected into the system prompt as a call objective
system_prompt
Replaces the default system prompt entirely
system_prompt + goal
Goal is appended to your custom prompt
Neither system_prompt nor goal
Default agent behavior with patient context only
Phone Number Selection
The caller ID is always resolved from the use case. Pass a use_case_id and the platform selects the optimal phone number based on the use case configuration (geography, capability, load balancing). The resolved number and setup ID are returned in the response.
Response:
Callback Chains
When a call is a follow-up to a previous conversation, pass derived_from_call_sid with the original call's identifier. This creates an explicit link in the world model so you can trace the full outreach sequence.
The patient's timeline will show both calls and the lineage between them.
External System Correlation
Use tags and metadata to connect calls to records in your other systems. These values are stored in the world model event and available in analytics.
Tags are useful for filtering calls in analytics dashboards. Metadata is useful for joining call outcomes back to your source systems.
Idempotency
To safely retry a request without creating a duplicate call, include an idempotency_key:
If you send the same idempotency_key again within the deduplication window, you get back the original response instead of placing a second call. If you omit the key, the platform generates one automatically (no deduplication across retries).
World Model Lineage
Every outbound call emits an outbound.initiated event on the patient entity's timeline the moment the call is created (before it connects). This event captures:
Who requested the call - the API key identifier (not the secret)
Why - the
reasonandgoalyou providedWhat external systems are involved - your
tagsandmetadataWhere it fits in a sequence -
derived_from_call_sidif this is a callback
The event_id in the response points to this event. You can use it to:
Correlate initiation with downstream call events (connected, completed, failed)
Query the patient's timeline to see all outreach attempts
Build analytics on API-initiated calls vs agent-scheduled calls vs trigger-driven calls
API-initiated calls appear in the same unified timeline as all other patient interactions.
Error Responses
400
Phone number is not valid E.164 format
Fix the request body. E.164 = + followed by 1-15 digits, first digit 1-9.
404
Patient entity does not exist in this workspace (or is not a person entity), or no phone number is available for the use_case_id
Verify the patient_entity_id exists via GET /v1/{workspace_id}/world/entities/{entity_id}. For use case 404s, check your phone number provisioning.
422
Missing required fields (phone_to, use_case_id, reason, or a patient identifier)
Add the missing fields. Every request requires phone_to, use_case_id, reason, and exactly one patient identifier (patient_entity_id or patient_canonical_id).
429
Rate limit exceeded
Back off and retry. The limit applies per API key and per route (scoped to /calls/outbound).
502
The voice infrastructure returned an error
Retry with the same idempotency_key. If persistent, check service status.
503
Voice agent or outbound calling is not configured for this workspace
Contact support to enable outbound calling.
504
Phone number selection timed out
Retry. If persistent, check phone number provisioning for the use case.
Rate Limits
The outbound call endpoint allows 1000 requests per minute, enforced per API key and per route. This limit is scoped to /calls/outbound only - it is not shared with other Platform API endpoints (other write endpoints use the standard 10 requests per minute write limit).
If you exceed the limit, you receive a 429 response. Use idempotency_key so you can safely retry after the rate limit resets.
Carrier-level constraints on individual phone numbers are enforced separately by the downstream voice carrier and are independent of this API rate limit.
Full Example
A CRM webhook fires when a patient's lab results are ready. Your backend calls the outbound API to notify them:
The agent receives the patient's full clinical context (conditions, medications, appointments) plus the goal. When the patient answers, the agent already knows their name, their A1C order, and what to discuss.
Troubleshooting
Call connects but patient hears silence/hold music
Agent failed to join the conference. Check that the voice agent service is running and the workspace has a valid service configuration.
Verify service_id is correct, or omit it to use the workspace default.
503 Service Unavailable
Outbound calling is not enabled for this workspace, or the voice infrastructure is temporarily unavailable.
Contact support to verify outbound calling is configured.
404 Not Found on patient_entity_id
The entity doesn't exist, isn't in this workspace, or isn't a person entity type.
Check the entity via GET /v1/{workspace_id}/world/entities/{entity_id}.
Call rings but goes to voicemail
The patient didn't answer. This is normal behavior - check call status via the call detail endpoint.
Consider retry logic with idempotency_key and derived_from_call_sid.
Agent speaks but has no patient context
patient_entity_id points to an entity with no enrichment data.
Verify the entity has been enriched via connectors or manual data entry.
Last updated
Was this helpful?

