Resia API
Resia places and answers phone calls for you. Its workflows can coordinate calls, messages, and waits.
Point your coding assistant at this
Don't want to read this doc yourself? Hand this one link to your agent.
It will know what to do!
Start here
Choose the task you want to complete. Each guide links to the relevant API operations.
Core Concepts
A Call Agent defines how Resia handles a conversation. A call is one attempt to use that agent. You can reuse the same Call Agent for many calls.
Call Agents and calls
A Call Agent contains the instructions and settings for a phone conversation. For example, an appointment agent can ask a caller which time they prefer. Change the agent when you want to change what Resia says or how it responds.
A call is one attempt to place or answer a phone call. Each call has its own ID, status, and results. Use the call ID to find its transcript, recording, or analysis when those results are available.
Phone numbers and call direction
A phone number belongs to your organization in Resia. You can select it as the caller number for outbound calls or assign a Call Agent to answer inbound calls.
For an outbound call, you send a request with a Call Agent ID, a destination number, and any inputs. Resia starts one call with that agent.
For an inbound call, you assign a Call Agent to your Resia number in advance. When someone dials that number, Resia answers with the assigned agent.
Both directions use the same Call Agent type. You can use separate agents when the conversations need different instructions.
Inputs and knowledge bases
Inputs are values for one call or workflow run, such as a caller's name or an appointment date. The agent's input schema defines which values it accepts and requires. The instructions can refer to these values through variables. See Change what an agent says for an example.
A knowledge base holds reference information that an agent can search, such as your service descriptions. Use it for information that the agent needs across conversations.
Analysis and webhooks
Analysis is a structured result that the agent produces after its task. The agent's analysis schema defines the result fields, such as whether the caller confirmed an appointment.
A webhook is an HTTP request that Resia sends to your server. An inbound webhook can supply caller-specific inputs before the conversation starts. A result webhook can notify your server after a call ends. See Get results after a call for the result format.
Workflow Agents and Workflow Runs
A Workflow Agent defines a task that can use several steps. For example, it can place a call, wait for the result, and decide whether another call is needed. Its approved configuration determines which actions it can take.
A Workflow Run is one execution of a Workflow Agent. Each run has its own progress and result.
For example, a workflow can call to confirm an appointment. If nobody answers, it can wait until a later time and try again within its limits. If the person confirms, it can finish with that result in its analysis. The instructions and available results determine the steps; every run does not follow the same sequence.
A run can also fail or be cancelled. Read its status and error details to distinguish those outcomes from success. The result webhook is optional. Text replies do not resume a workflow run.
You do not need a Workflow Agent to make an outbound call or receive an inbound call.
API reference: Call Agents and Start a Workflow Run.
Get access to Resia
Use the Resia portal to manage your account and API keys. An API key lets your software act for your organization. It does not sign you into the portal.
Join the correct organization
- Open your organization's invitation link, if you received one.
- Sign in with Google or GitHub with the email address on the invitation.
- Accept the invitation.
If your team already uses Resia, ask a member for an invitation before you create another organization. A person can belong to one organization. If you are the first person on a new account, create your organization in the portal.
Already have a key, but cannot see your account? A key does not establish your personal account membership. Ask your Resia contact to connect your login to the existing organization. For account help, email support@resia.ai. Include your account email and organization name. Do not send your API key.
Create an API key
- Open API Keys in the portal.
- Select Create credential.
- Enter a name that identifies the software that will use the key.
- Copy the complete key to your secret store before you close the result.
Resia shows the secret once. If you lose it, create a replacement. Update your software before you revoke the old key. Revocation stops that key immediately.
Prepare your terminal
The examples use a Bash terminal with curl, jq, and uuidgen installed.
curl sends requests. jq reads and builds JSON, the data format used by the API.
uuidgen creates a unique key for each new call request.
Run bash first if your terminal uses another shell.
export RESIA_API_BASE='https://api.resia.ai'
read -r -s -p 'Resia API key: ' RESIA_API_KEY
printf '\n'
export RESIA_API_KEY
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/call-agents?limit=1" \
--header "Authorization: Bearer $RESIA_API_KEY"
Expected result: HTTP 200 and a JSON object with an items list. An empty list is valid.
Keep this terminal open for the other guides.
If it fails: HTTP 401 means the credential was not accepted. Check that you copied the complete, active key.
An API key cannot create other keys or manage account membership. Those operations need a signed-in person.
API reference: List Call Agents.
Make an Outbound Call
This guide creates a simple Call Agent, then places one real call to your phone. A Call Agent stores the instructions that a phone conversation follows. The call can incur normal call charges.
Before you start
- Complete Get access to Resia.
- Keep the same Bash terminal open, with
RESIA_API_BASEandRESIA_API_KEYset. - Use a phone you control in the United States or Canada. Premium-rate destinations are not supported.
Create a test agent
Copy this block into your terminal. The two schemas describe the allowed input and the result after the call. This agent needs no input values.
cat > first-agent.json <<'JSON'
{
"name": "My first Resia call",
"instructions": "You are a friendly test assistant. Say hello and explain that this is a Resia test call. Ask whether the person can hear you clearly. Thank them and end the call.",
"input_schema": {"type": "object", "properties": {}, "additionalProperties": false},
"analysis_prompt": "Summarize the conversation in one sentence.",
"analysis_schema": {
"type": "object",
"properties": {"summary": {"type": "string"}},
"required": ["summary"],
"additionalProperties": false
},
"agent_speaks_first": true,
"should_leave_voicemail": false
}
JSON
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/call-agents" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--header 'Content-Type: application/json' \
--data-binary @first-agent.json \
--output agent-response.json
jq '{id, review_status, is_active}' agent-response.json
Expected result: HTTP 201, an id, and the agent's review state.
Continue only when review_status is approved and is_active is true.
If the agent needs review, contact Resia. Do not repeatedly create the same agent.
If its name already exists, choose another name or use the existing agent's id.
API reference: Create a Call Agent.
Call your phone
Enter your own number with + and its country code, such as +12125550142.
The example number shows the format; replace it with your number.
CALL_AGENT_ID=$(jq -er '.id' agent-response.json)
read -r -p 'Your phone number, including + and country code: ' TO_PHONE_NUMBER
CALL_REQUEST_KEY=$(uuidgen)
jq -n --arg agent "$CALL_AGENT_ID" --arg phone "$TO_PHONE_NUMBER" \
'{call_agent_id: $agent, to_phone_number: $phone, inputs: {}}' > first-call.json
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/calls" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--header 'Content-Type: application/json' \
--header "Idempotency-Key: $CALL_REQUEST_KEY" \
--data-binary @first-call.json \
--output call-response.json
jq '{id, status}' call-response.json
Expected result: HTTP 202 and a call id. Resia accepted the request; this does not mean the phone answered.
Answer your phone when it rings.
The Idempotency-Key identifies this one call request.
To retry an uncertain request, repeat the curl command with the same key and body.
To place another call intentionally, generate a new key. The same key returns the original call.
This example uses Resia's default caller number.
To select a number your organization owns, supply from_phone_number in the request body.
API reference: Place a call.
Read the result
CALL_ID=$(jq -er '.id' call-response.json)
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/calls/$CALL_ID" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--output call-result.json
jq '{id, status, transcript, analysis, failure}' call-result.json
Repeat this read after the call ends. The final status is completed, error, or canceled.
An unknown status means Resia cannot read the live status at that moment; it is not a final result.
Inspect the transcript and analysis to confirm what happened. A completed call does not prove that a person answered.
If it fails: Read the error message. A 422 response identifies invalid inputs or an unusable agent.
A 429 response means a call limit blocked the request. Wait before another attempt.
If an accepted call fails, inspect its failure field.
Next: Get results after a call.
Receive an inbound call
An incoming call is an inbound call. Assign a Call Agent to a Resia phone number to answer it.
You do not send POST /v1/calls to receive a call.
This guide also covers the Resia side of call forwarding and return calls.
Before you start
- Complete Get access to Resia.
- Create an active Call Agent, such as the agent in Make an Outbound Call.
- Use a Resia number that your organization owns and can use for this test.
For your first inbound test, use an agent with no required input values or placeholders.
Set agent_speaks_first to true if the agent should greet the caller immediately.
Find your Resia number
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/phone-numbers" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--output phone-numbers.json
jq '.items[] | {phone_number, inbound_call_agent_id}' phone-numbers.json
Expected result: Each item shows a number and the agent that currently answers it, or null if none does.
If next_cursor is not null, another page exists.
If you have no number, use the number purchase reference or contact Resia.
A number purchase and monthly rental have separate charges.
API reference: List your phone numbers.
Assign the agent
This action changes which agent answers new calls to the selected number. Record the current assignment before you replace it.
read -r -p 'Your Resia number, including + and country code: ' RESIA_PHONE_NUMBER
read -r -p 'The active Call Agent id: ' CALL_AGENT_ID
jq -n --arg agent "$CALL_AGENT_ID" \
'{inbound_call_agent_id: $agent}' > inbound-assignment.json
curl --fail-with-body --silent --show-error \
--request PATCH "$RESIA_API_BASE/v1/phone-numbers/$RESIA_PHONE_NUMBER" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--header 'Content-Type: application/json' \
--data-binary @inbound-assignment.json
Expected result: HTTP 200 with the selected inbound_call_agent_id.
The path contains the full phone number, not a phone number record ID.
API reference: Assign an inbound Call Agent.
Test before call forwarding
- Call the Resia number directly from another phone.
- Confirm that the expected agent answers.
- Inspect the result with Get results after a call.
- Configure your existing phone provider to forward calls to this Resia number.
- Call your original number to test the complete path.
Your phone provider controls call forwarding, including its hours and unanswered-call rules.
The Resia assignment does not configure that provider.
To restore the previous agent, repeat the assignment with its ID.
To stop Resia from answering on the number, send {"inbound_call_agent_id": null} through the same PATCH operation.
Add caller-specific information later
A webhook is an HTTP request that Resia sends to your server.
For inbound personalization, set inbound_input_webhook_url on the Call Agent through the agent edit guide.
This URL is optional. The first test above does not need it.
Resia sends this shape to your HTTPS URL before the call answers:
{
"type": "call.incoming",
"call": {
"from_phone_number": "+12125550142",
"to_phone_number": "+16465550175"
}
}
Reply within 30 seconds with HTTP 200 and a flat JSON object that matches the agent's input_schema.
For example, an agent that declares topic can receive {"topic": "office hours"}.
Every placeholder in its instructions also needs a value.
Resia puts those values into the instructions before the agent answers. If the request fails, the call can still answer only if the agent can run with empty inputs. Otherwise, the call rings out. Your webhook must tolerate duplicate requests without side effects.
If the phone does not answer: Check the number assignment, agent activation, and required inputs first. If a webhook is configured, inspect request logs for its response or timeout.
Change what an agent says
Edit the Call Agent's instructions to change the conversation.
The same edit process applies to agents for outbound and inbound calls.
Important: PUT replaces the complete configuration. It is not a partial update.
Keep every setting that should remain, including voices, webhooks, and participant settings.
An omitted optional setting can clear its current value.
Read the agent before you edit it
Complete Get access to Resia first. Use the Call Agent ID, not the ID of a call.
read -r -p 'Call Agent id: ' CALL_AGENT_ID
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/call-agents/$CALL_AGENT_ID" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--output agent-current.json
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/openapi.json" --output resia-openapi.json
jq --slurpfile api resia-openapi.json \
'with_entries(select(.key as $key | $api[0].components.schemas.CallAgentWrite.properties | has($key)))' \
agent-current.json > agent-update.json
The last command keeps fields that the API accepts for an agent update.
It removes response-only fields such as id and review_status.
Keep agent-current.json as a record of the configuration you read.
API reference: Read a Call Agent.
Change the instructions
Open agent-update.json in your text editor.
Change instructions to describe the conversation you want.
Keep the other fields unless you intend to change them.
Avoid simultaneous edits by two people; a later complete update can overwrite an earlier one.
For a greeting on an inbound call, set agent_speaks_first to true.
To leave a message when an outbound call reaches voicemail, set should_leave_voicemail to true.
Neither setting creates an inbound number assignment.
Use variables correctly
Use $topic or ${topic} to insert the top-level input named topic.
Use $$ for a literal dollar sign. Do not use {{topic}} or a nested path such as $person.name.
For example, this instruction uses one variable:
You are a helpful assistant. Ask the person one question about $topic.
Declare that variable in input_schema:
{
"type": "object",
"properties": {"topic": {"type": "string"}},
"required": ["topic"],
"additionalProperties": false
}
For an outbound call, pass {"topic": "office hours"} in the call's inputs.
For an inbound call, return that object from the inbound webhook.
Every referenced placeholder needs a value, even if the schema marks its property as optional.
Save the complete configuration
curl --fail-with-body --silent --show-error \
--request PUT "$RESIA_API_BASE/v1/call-agents/$CALL_AGENT_ID" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--header 'Content-Type: application/json' \
--data-binary @agent-update.json \
--output agent-updated.json
jq '{id, review_status, is_active, active_updated_at}' agent-updated.json
Expected result: HTTP 200 and the same agent id.
New instructions can need review. While review is pending, calls continue to use the previous active instructions.
Agent settings such as webhook URLs can take effect immediately, before instruction approval.
Confirm review_status is approved before a test of the new instructions.
An is_active value of true alone can describe the previous active version.
If it fails: A 422 response can identify invalid JSON, missing required fields, an invalid schema, or an undeclared placeholder.
Read the error message before you resend the update.
API reference: Replace a Call Agent.
Get results after a call
You can read a call by ID or receive a webhook when it ends. A webhook is an HTTP request that Resia sends to your server. Both paths use the same call result shape.
Find a call
Complete Get access to Resia first.
An outbound call request returns the call id immediately.
For incoming calls, use the call list to find the new record:
read -r -p 'Call Agent id: ' CALL_AGENT_ID
curl --fail-with-body --silent --show-error --get \
"$RESIA_API_BASE/v1/calls" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--data-urlencode "call_agent_id=$CALL_AGENT_ID" \
--data-urlencode 'limit=10' \
--output recent-calls.json
jq '.items[] | {id, status, created_at, from_phone_number, to_phone_number}' recent-calls.json
Choose the call that matches the time and phone numbers of your test.
The list puts the newest records first. Follow next_cursor if the call is on a later page.
read -r -p 'Call id: ' CALL_ID
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/calls/$CALL_ID" \
--header "Authorization: Bearer $RESIA_API_KEY" \
--output call-result.json
jq '{id, status, transcript, analysis, failure}' call-result.json
Expected result: HTTP 200 with the call record.
While the call is active, the transcript and analysis can be incomplete or absent.
Read the result again after the call ends.
Check failure when the status is error. Check the transcript and analysis to confirm the customer's actual result.
The status completed alone does not prove that a human answered or that the task succeeded.
API reference: List calls and Read a call.
Receive a result notification
- Prepare an HTTPS endpoint on your server to receive JSON requests.
- Follow Change what an agent says to prepare a complete agent update.
- Set
call_ended_webhook_urlto your endpoint inagent-update.json. - Submit that complete update.
- Place or receive a new test call with the agent.
Resia sends a call.ended event when a call reaches completed, error, or canceled.
The following example shows the event with the required call fields. Actual events can include additional call details.
{
"type": "call.ended",
"call": {
"id": "01K1SA3F7M8QW2V5C9H4YTB0KD",
"call_agent_version_id": "01K1S9V9Q0RS7X4T2N6BJ8ZDE5",
"call_agent_id": "01K1S7RA9M8QW2V5C9H4YTB0AG",
"call_agent_name": "Front desk",
"status": "completed",
"created_at": "2026-09-15T14:00:00.000+00:00"
}
}
Read the record under call, not data. Its id is the same ID used by GET /v1/calls/{call_id}.
The record reflects the data available when Resia sends the event.
- Return a
2xxresponse after you accept the event. - Treat a repeated
call.idas a duplicate. Do not repeat your business action for that call. - Expect retries after a failed delivery: Resia makes up to six attempts over about 8.6 hours.
- Protect the complete webhook URL. Delivery uses HTTPS and URL secrecy; it has no signature header.
You can put your own verification token in the URL. Resia stores and logs that URL, so restrict access to those records. Never use your Resia API key as the webhook token.
The result webhook differs from inbound_input_webhook_url, which supplies inputs before an incoming call answers.
You can use either webhook without the other.
API reference: Call ended event.
Diagnose a missing notification
curl --fail-with-body --silent --show-error \
"$RESIA_API_BASE/v1/request-logs?kind=webhook&limit=10" \
--header "Authorization: Bearer $RESIA_API_KEY"
Each webhook attempt has a request log. Read a log's details to inspect its request and response. Check your server's availability and response status if a delivery fails. If all attempts fail, use the call read operation to recover the result. For support, include the call ID and request ID. Do not send keys or private call content.
API reference: Request logs.
API reference
Changes to this API
Every change to this contract is listed at /changelog, newest first, with the ones
that would break an existing client marked — or as machine-readable JSON at
/changelog.json. The version above is the contract this environment is serving.

