Sarj AI Developer API · AsyncAPI Specification
Sarj Ai Developer Api Webhooks
Version
View Spec
View on GitHub
Voice AIVoice AgentsConversational AIArabic AIOutbound CallsTelephonySpeech-to-TextText-to-SpeechVoice CloningMCPAgent-NativeSaudi ArabiaMENAA2AAsyncAPIEvents
AsyncAPI Specification
generated: '2026-09-11'
method: searched
source: https://platform-docs.sarj.ai/webhooks
spec_type: Webhooks
asyncapi_published: false
asyncapi_note: >-
Sarj publishes no AsyncAPI document. Probes for /asyncapi.yaml and /asyncapi.json on every host missed, the docs
sitemap lists no event-catalog page, and the GitHub org holds no spec repo. The event surface below is captured from
the provider's prose webhook documentation — it is a faithful catalog of what they publish, not a fabricated spec.
transport: https
delivery: push
direction: provider-to-consumer
configuration:
where: https://platform.sarj.ai
granularity: one webhook URL per organization
per_event_filtering: false
note: >-
A single URL per organization, configured only in the dashboard. There is no API to register, list, rotate or
delete a webhook endpoint, and no way to subscribe to a subset of event types.
endpoint_requirements:
- Reachable over HTTPS (HTTP works for staging but is not recommended)
- Return 2xx within 10 seconds
- Be idempotent — deduplicate on call_id
envelope:
shape: '{"call_id": "...", "payload": {...}}'
discriminator: payload.type
events:
- type: complete
summary: Call reached the customer and finished.
fires_when: The call reached a terminal completed state.
payload_fields:
- call_started
- call_data.call_id
- call_data.direction
- call_data.phone_number
- call_data.status
- call_data.total_duration
- call_data.enhanced_transcript.transcript.messages
- call_data.enhanced_transcript.errors
- call_data.report
- call_data.recording_url
- call_data.created_at
- call_data.started_at
- call_data.ended_at
- response_body
note: >-
The only variant carrying a body. Includes the full signed recording URL, transcript and report — the same data
getCall returns, pushed the moment it is available.
- type: no_answer
summary: Rang, no pickup.
payload_fields: [type]
- type: user_rejected
summary: Customer hung up or rejected the call.
payload_fields: [type]
- type: user_unavailable
summary: Carrier returned unavailable (phone off, out of coverage).
payload_fields: [type]
- type: automation
summary: Hit an IVR, voicemail or other non-human answer.
payload_fields: [type]
- type: rejected_by_carrier
summary: The carrier refused the call.
payload_fields: [type, retry_attempt_number, root_call_id, next_retry_at]
added: '2026-09-11'
- type: invalid_number
summary: The number could not be dialed.
payload_fields: [type, retry_attempt_number, root_call_id, next_retry_at]
added: '2026-09-11'
- type: sip_trunk_failure
summary: Telephony trunk failure before ringing.
payload_fields: [type, retry_attempt_number, root_call_id, next_retry_at]
added: '2026-09-11'
- type: cancelled
summary: A scheduled call or pending retry was cancelled before dialing.
payload_fields: [type, retry_attempt_number, root_call_id, next_retry_at]
added: '2026-09-11'
note: >-
The webhook side of cancelScheduledCall — the reversal operation emits its own event, so a receiver
learns that an agent (or a person) stopped a booked call.
- type: expired
summary: A scheduled call or pending retry expired before dialing.
payload_fields: [type, retry_attempt_number, root_call_id, next_retry_at]
added: '2026-09-11'
- type: failed
summary: Telephony failure with no SIP-level reason.
payload_fields: [type, retry_attempt_number, root_call_id, next_retry_at]
retry_chain_correlation:
added: '2026-09-11'
detail: >-
Documented since the 2026-08 pass. Every dial in a retry group is its own call with its own webhook, and
both payload variants now carry three correlation fields.
fields:
- name: retry_attempt_number
meaning: Which dial this was (1, 2, 3 ...).
- name: root_call_id
meaning: >-
The first attempt's call_id, shared by every retry in the group; null on the first attempt itself.
- name: next_retry_at
meaning: >-
When the next attempt is booked to dial. null means no more attempts are coming — that webhook is the
group's last word.
consumer_guidance: >-
next_retry_at == null is the terminal signal for a contact, not the call status. A receiver that treats
each no_answer as final will double-count a single person; a receiver that waits for a `complete` that
never arrives will hang forever.
retries:
attempts: 3
backoff: fixed
delay_seconds: 2
per_attempt_timeout_seconds: 10
triggers: [network error, timeout, non-2xx response]
after_exhaustion: >-
Delivery is marked failed and the per-call webhook state is recorded server-side. The data remains durable and
re-fetchable via getCall.
security:
signature_verification: false
signature_note: >-
HMAC webhook signature verification is documented as "not yet shipped". The provider's own guidance is to lock the
endpoint down by IP allow-listing (source range from support) or by adding a hard-to-guess secret path component
to the URL.
gap: >-
This is the most significant security gap on the event surface. Without signatures a receiver cannot verify that a
completed-call payload — which carries a transcript, a signed recording URL and the outcome report — actually came
from Sarj. Obscurity of the URL path is the only control offered.
testing:
dashboard_button: 'Send test webhook'
behavior: Fires a synthetic `complete` payload at the configured URL.
then: Place a real test call to verify end-to-end.
findings:
- id: no-asyncapi
detail: >-
The event surface is real, well-documented and typed by a payload.type discriminator — it is a good candidate
for an AsyncAPI 3.x document. Publishing one would make the eleven event variants and the three retry
correlation fields machine-readable alongside the OpenAPI. Re-probed 2026-09-11: /asyncapi.yaml and
/asyncapi.json still 404 on every host and the docs sitemap (now thirteen pages) has no event-catalog
page.
- id: no-webhook-management-api
detail: Endpoints are dashboard-only, so webhook configuration cannot be automated or managed as code.
- id: event-catalog-grew-without-announcement
detail: >-
Five event types (rejected_by_carrier, invalid_number, sip_trunk_failure, cancelled, expired) and three
correlation fields were added to the documented webhook surface between 2026-08 and 2026-09. A receiver
switching on payload.type with an exhaustive match would have started hitting its default branch with
no notice — there is no changelog.
x-evidence:
- url: https://platform-docs.sarj.ai/webhooks
http_status: 200
- url: https://platform-docs.sarj.ai/sitemap.xml
http_status: 200
note: Thirteen pages total (2026-09-11); no event-catalog or AsyncAPI page.
Work with this as data
Every AsyncAPI spec here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for asyncapi
4 MCP tools reach this
find_asyncapisBrowse and filter every AsyncAPI spec in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This AsyncAPI spec
curl "https://apis.io/api/v1/asyncapis/sarj-ai-developer-api-webhooks"
All asyncapi
curl "https://apis.io/api/v1/asyncapis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.