QuillAIQuillAIDocs
Sign in
API ReferenceWebhooks

Webhooks

Skip polling. When you create a transcription, pass a webhook_url and we push the finished payload to your server the moment it's ready.

TL;DR: include webhook_url in your POST /v1/transcriptions call — the finished payload will land at that URL. Pick an unguessable path; deliveries are not signed.

Register a webhook

There's no separate subscription resource — a webhook is bound to a single transcription via the webhook_url field at creation time. Use any HTTPS URL you control.

register.shbash
curl -X POST https://api.quillhub.ai/v1/transcriptions \
  -H "Authorization: Bearer $QAI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://youtu.be/dQw4w9WgXcQ",
    "webhook_url": "https://your-app.example.com/hooks/quillai"
  }'

Events

Exactly one event fires per transcription, once it reaches a terminal state:

  • transcription.completedtranscription finished successfully; result is populated.
  • transcription.failedtranscription failed; error contains the reason and no points are charged.

Payload

The body is the full Transcription object — the same shape returned by GET /v1/transcriptions/{id}. See the API reference for the complete schema.

payload.jsonjson
{
  "id": "trs_01HZX9K7Q2M4YV8BTA6JRN3PDE",
  "status": "completed",
  "source": { "type": "youtube", "url": "https://youtu.be/dQw4w9WgXcQ" },
  "duration_seconds": 842,
  "points_spent": 14,
  "result": {
    "text": "Welcome back to the channel. Today we're talking about...",
    "segments": [ /* ... */ ],
    "structured": { /* ... */ },
    "subtitles": {
      "vtt": "https://storage.quillhub.ai/subtitles/...vtt",
      "srt": "https://storage.quillhub.ai/subtitles/...srt"
    }
  },
  "webhook_url": "https://your-app.example.com/hooks/quillai",
  "error": null,
  "created_at": "2026-04-23T10:12:03Z",
  "completed_at": "2026-04-23T10:14:27Z"
}

Headers

  • X-QuillAI-Eventthe event type, either transcription.completed or transcription.failed.
  • X-QuillAI-Deliverya unique UUID for this delivery attempt. Use it to dedupe if a retry arrives after you already processed the first call.

We also send Content-Type: application/json and User-Agent: QuillAI-Webhooks/1.0.

Retries

A delivery succeeds when your endpoint returns a 2xx status within 10 seconds. Anything else — non-2xx, timeout, connection error — triggers retries on a fixed schedule: 1 minute, 5 minutes, 30 minutes, 2 hours, 12 hours. After 5 retries (6 attempts total) the delivery is abandoned and no further attempts are made for that event.

Testing locally

There's no sandbox endpoint for webhooks yet. To test against local code, expose your dev server with a tunnel like ngrok or smee.io and use the resulting public URL as webhook_url on a qai_test_ key.