Skip to main content

Receive PyAI completion events

Use webhooks for background completion events. Streaming Hear transcripts and Omni audio arrive on their live connection; they are not webhook events.

Choose the event family

These families have different payloads. Read the async job guide, Recap guide, or integration guide for the exact event you are receiving. Do not assume one universal event schema.

Configure an async job callback

Replace the audio and callback URLs with your own HTTPS URLs:
Choose a distinct idempotency key per logical job. For an uncertain response, retry the same request with the same key. You can also poll GET /v1/transcription/jobs/{job_id} for its status.

Obtain the signing secret

Use your organization’s webhook signing secret, which is separate from the API key. The authenticated POST /v1/webhooks/signing-secret operation mints or rotates it. Coordinate rotation with your existing receivers; do not rotate a working organization’s secret just to run this example. Store the secret as PYAI_WEBHOOK_SECRET on the receiving server.

Verify before parsing

PyAI sends the header X-PyAI-Signature in this form:
Read the raw request bytes before JSON middleware changes whitespace or key ordering. Verify the digest with a constant-time comparison and enforce a timestamp tolerance. The starter uses five minutes, so keep the receiver clock synchronized. A recent signature alone does not prevent duplicate delivery.

Run the receiver

Requires Node.js 22+, curl, and tar. The archive contains a server, signature verifier, tests, and .env.example. It has no npm dependencies.
Expose port 8080 over HTTPS and set /webhooks/pyai as your callback path. The receiver validates the signature, stores the event in a private local inbox/ directory, then returns 204. It rejects invalid signatures and stale timestamps. This is a development inbox; use a durable store or queue in production. Payloads may contain transcripts, so apply your access and retention policy to stored events.

Delivery handling

  • Acknowledge only after accepting the event into durable storage or a queue.
  • Handle the work outside the HTTP request and make side effects idempotent.
  • For async jobs, track X-PyAI-Event-Id or Idempotency-Key; for integration envelopes, use the event id. Recap consumers should use call identity and the documented event semantics. Headers are not covered by the body HMAC; also check the signed payload identity before suppressing an event.
  • The demo deduplicates identical signed bodies. Production deduplication must cover your event family and survive process restarts and multiple replicas.
  • Expect retries; retry schedules depend on the product. Use job status APIs to reconcile an async result when a callback is missing.
Twilio sends X-Twilio-Signature, which uses Twilio’s own validation scheme and auth token. Use the Twilio starter for those requests; do not run them through the PyAI HMAC verifier.

Troubleshooting

Getting started · API reference · Documentation index