# Rev AI Webhooks

Rev AI's asynchronous speech-to-text API sends one webhook (an HTTP POST) when a transcription
job finishes: `job.status` is `transcribed` or `failed`. Payloads are **not signed**. The
credential is the `Authorization` header you attach to the job in `notification_config`.

## When to Use This Skill

* How do I receive Rev AI webhooks?
* How do I authenticate a Rev AI `notification_config` callback?
* Does Rev AI sign webhook payloads? (No: a static Authorization header only)
* Why does my Rev AI webhook endpoint return 401?
* How do I handle `transcribed` and `failed` job notifications and fetch the transcript?

## Verification (core)

Submit the job with `notification_config` and an `auth_headers` object. `Authorization` is the
only header allowed and its value must be `<scheme> <token>`:

```json
{ "notification_config": { "url": "https://example.com/webhooks/rev-ai",
                           "auth_headers": { "Authorization": "Bearer <token>" } } }

```

Rev AI then sends that header on the callback. The key is the **whole header value, scheme
prefix included**: compare the full `Authorization` header to `REV_AI_AUTHORIZATION`
(e.g. `Bearer <token>`). Don't strip or parse the prefix:

```javascript
const crypto = require('crypto');

// Hash both sides: equal-length buffers, so timingSafeEqual never throws.
function safeEqual(a, b) {
  const ha = crypto.createHash('sha256').update(String(a)).digest();
  const hb = crypto.createHash('sha256').update(String(b)).digest();
  return crypto.timingSafeEqual(ha, hb);
}

function verifyRevAiRequest(headers, expected = process.env.REV_AI_AUTHORIZATION) {
  if (!expected) return false;                 // never accept when unconfigured
  const received = headers['authorization'];   // full value, e.g. "Bearer abc123"
  return Boolean(received) && safeEqual(received, expected);
}

```

Return `401` when this fails, `400` for a body that isn't a JSON object, and `200` once
handled. Read the body raw (`express.raw({ type: '*/*' })`) and parse JSON only after the check.
Python and Next.js equivalents are in [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/rev-ai-webhooks/references/verification.md).

> **Limits of a static credential:** it authenticates the sender, not the body, and gives no
> replay protection (no signature, no timestamp). Use HTTPS only, and rotate the credential if
> it leaks. The deprecated `callback_url` field carries no auth at all, so use `notification_config`.

> **For complete handlers with tests**, see [examples/express/](https://github.com/hookdeck/webhook-skills/tree/main/skills/rev-ai-webhooks/examples/express/),
> [examples/nextjs/](https://github.com/hookdeck/webhook-skills/tree/main/skills/rev-ai-webhooks/examples/nextjs/), [examples/fastapi/](https://github.com/hookdeck/webhook-skills/tree/main/skills/rev-ai-webhooks/examples/fastapi/).

## Job Statuses in Webhooks

The webhook body is `{ "job": { ... } }`. Rev AI sends it only when a job completes or fails:

| `job.status` | Meaning | Useful fields |
| --- | --- | --- |
| `transcribed` | Transcript is ready | `id`, `created_on`, `completed_on`, `duration_seconds` |
| `failed` | Job failed | `failure` (e.g. `download_failure`), `failure_detail` |

After `transcribed`, fetch the transcript with `GET /speechtotext/v1/jobs/{id}/transcript`.
Rev AI retries every 30 minutes for up to 24 hours until your endpoint returns `200`.

## Environment Variables

```bash
REV_AI_AUTHORIZATION=Bearer replace-with-a-long-random-token   # full header value

```

## Local Development

```bash
npx hookdeck-cli listen 3000 rev-ai --path /webhooks/rev-ai

```

No account required. Use the printed URL as `notification_config.url`.

## Resources

* [references/overview.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/rev-ai-webhooks/references/overview.md) - Job webhook payloads, statuses, failure codes, retries
* [references/setup.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/rev-ai-webhooks/references/setup.md) - Submitting jobs with notification_config and auth_headers
* [references/verification.md](https://github.com/hookdeck/webhook-skills/blob/main/skills/rev-ai-webhooks/references/verification.md) - Header check in Node, Python and Next.js, gotchas
* [examples/](https://github.com/hookdeck/webhook-skills/tree/main/skills/rev-ai-webhooks/examples/) - Runnable Express, Next.js and FastAPI handlers with tests