For the complete documentation index, see llms.txt. This page is also available as Markdown.

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

Field
Type
Description

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.

Optional Fields

Field
Type
Description

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)

Field
Type
Description

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:

  1. Validation - The platform verifies the patient entity exists, resolves the caller ID, and queues the call with the downstream voice carrier.

  2. 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.

  3. 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.

  4. Conversation - The call proceeds exactly like an inbound call. The agent has full access to tools, clinical context, and the conversation state machine.

  5. 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 ringingin-progresscompleted (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.

You provide
The agent gets

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 reason and goal you provided

  • What external systems are involved - your tags and metadata

  • Where it fits in a sequence - derived_from_call_sid if 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

Status
When
What to do

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

Symptom
Cause
Fix

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?