Webhooks

A webhook is an HTTPS request that Resia sends to your server when something happens. Resia sends five events:

Event When Configure with Your reply
call.ended A call reaches completed, error, or canceled. call_ended_webhook_url on the Call Agent, or on one call Any 2xx
chat.ended A chat reaches completed, failed, or cancelled. chat_ended_webhook_url on the Chat Agent Any 2xx
workflow_run.ended A run reaches succeeded, failed, or cancelled. run_ended_webhook_url on the Workflow Agent, or on one run Any 2xx
call.incoming An inbound call arrives on your number. inbound_input_webhook_url on the Call Agent 200 with inputs, within 30 seconds
chat.incoming A text starts a new chat on your number. inbound_input_webhook_url on the Chat Agent 200 with inputs, or 404 to refuse, within 30 seconds

Result events

call.ended, chat.ended, and workflow_run.ended carry the same record that the matching GET request returns, built when Resia sends the event.

{
  "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"
  }
}

The record is under call, chat, or workflow_run. Real events include more fields, such as the transcript and analysis.

Delivery rules:

  • Reply with any 2xx status as soon as you accept the event. Do slow work after you reply.
  • If delivery fails, Resia retries on a fixed schedule: up to 6 attempts over about 8.6 hours.
  • The same event can arrive more than once. Use the record's ID (call.id, chat.id, or workflow_run.workflow_run_id) to ignore duplicates.
  • If every attempt fails, read the record with a GET request to recover it.

Inbound events

call.incoming and chat.incoming let your server supply inputs before the conversation starts, such as the caller's name from your CRM.

{
  "type": "call.incoming",
  "call": {
    "from_phone_number": "+12125550142",
    "to_phone_number": "+16465550175"
  }
}

Reply within 30 seconds with HTTP 200 and this envelope. inputs must match the agent's input_schema:

{"inputs": {"patient_name": "Ada"}}

Resia makes one attempt and does not retry. If the reply is late, not 200, or not valid:

  • Call Agent: the call answers with empty inputs if the agent can run without inputs. Otherwise the call rings out.
  • Chat Agent: no chat starts, and Resia sends no reply. So chat.incoming works as an allow list: answer 200 for people you know and 404 for anyone else.

The inbound events never include what the person says or writes. Your endpoint must be read-only and must tolerate duplicate requests.

Security

Webhook requests have no signature header. Authenticity comes from HTTPS and from the secrecy of the URL.

  • Put your own random token in the URL, such as https://example.com/resia/webhook?token=..., and check it on every request.
  • Treat the complete URL as a secret.
  • Never use your Resia API key as the token.
  • Resia stores webhook URLs, returns them on reads, and shows them in request logs. Limit who can read those records.

Debugging

Every webhook attempt appears in request logs with its request, your response, and its status:

curl --fail-with-body --silent --show-error \
  "$RESIA_API_BASE/v1/request-logs?kind=webhook&limit=10" \
  --header "Authorization: Bearer $RESIA_API_KEY"

API reference: each event is documented under the Webhooks section of the API reference.