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

Raw ↑
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.
All 92 tools →

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.