Webhooks
A production event, delivered to your endpoint
Raylight POSTs one event per delivery to each subscribed endpoint. Verify Raylight-Signature against the raw body before parsing (t=<unix seconds>,v1=<hex HMAC-SHA256 of "<t>.<raw body>">, two v1 entries while a rolled secret is live, 5 minute tolerance). Dedupe on Raylight-Event-Id. data.production is the production as the API returns it, except that every code file in the brief has source and patch emptied and carries sourceOmitted: true; read the production over the API for the full files. A redelivered event has its own id and redeliveryOf naming the original. New event types and enum values are added without a version bump; acknowledge types you do not know with a 2xx.
your endpoint URLSent by Raylight, signed with your endpoint's secret. Check Raylight-Signature before trusting the body.
Headers
| Field | In | Type | Description |
|---|---|---|---|
raylight-signaturerequired | header | string | t=<unix seconds>,v1=<hex HMAC-SHA256>[,v1=...] |
raylight-event-idrequired | header | string | Stable across retries; dedupe on it. |
raylight-event-typerequired | header | string | The payload's type. |
Payload
application/json
| Field | Type | Description |
|---|---|---|
idrequired | uuid | |
typerequired | enum | One of: production.pitch_ready, production.skipped, production.greenlit, production.progress, production.delivered, production.failed, production.declined, production.cancelled, ping |
createdAtrequired | datetime | |
workspaceIdrequired | uuid | |
redeliveryOf | uuid | |
datarequired | object | |
data.production | object | |
data.production.idrequired | uuid | |
data.production.workspaceIdrequired | uuid | |
data.production.stagerequired | enum | One of: queued, writing_pitch, pitch_ready, greenlit, making, exporting, delivered, skipped, declined, cancelled, failed |
data.production.sourcerequired | object | |
data.production.source.kindrequired | enum | One of: app, api, mcp |
data.production.source.externalIdrequired | string | null | |
data.production.source.origin | object | null | Default null |
data.production.source.origin.providerrequired | string | |
data.production.source.origin.labelrequired | string | |
data.production.source.origin.url | url | null | Default null |
data.production.source.origin.ref | string | null | Default null |
data.production.source.origin.requestedBy | string | null | Default null |
data.production.briefrequired | object | |
data.production.brief.intentrequired | string | |
data.production.brief.context | string | null | Default null |
data.production.brief.media | object[] | |
data.production.brief.media[].idrequired | string | |
data.production.brief.media[].kindrequired | enum | One of: image, video |
data.production.brief.media[].urlrequired | url | |
data.production.brief.media[].namerequired | string | |
data.production.brief.media[].description | string | null | Default null |
data.production.brief.code | object[] | |
data.production.brief.code[].pathrequired | string | |
data.production.brief.code[].sourcerequired | string | |
data.production.brief.code[].status | enum | null | One of: added, modified, removed, renamedDefault null |
data.production.brief.code[].additions | integer | Default 0 |
data.production.brief.code[].deletions | integer | Default 0 |
data.production.brief.code[].patch | string | null | Default null |
data.production.brief.code[].digest | string | null | Default null |
data.production.brief.code[].score | number | Default 0 |
data.production.brief.code[].sourceOmitted | boolean | |
data.production.brief.format | object | |
data.production.brief.format.template | enum | One of: changelog, launch, feature, digest, customDefault changelog |
data.production.brief.format.durationMs | integer | Default 10000 |
data.production.brief.format.aspect | enum | One of: 16:9, 4:3, 3:2, 21:9, 1:1, 9:16, 3:4, 2:3, 4:5Default 16:9 |
data.production.brief.format.sound | object | |
data.production.brief.brand | object | |
data.production.brief.brand.name | string | null | Default null |
data.production.brief.brand.logoUrl | url | null | Default null |
data.production.brief.brand.primaryColor | string | null | Default null |
data.production.brief.brand.backgroundColor | string | null | Default null |
data.production.brief.brand.fontFamily | string | null | Default null |
data.production.brief.brand.tone | string | null | Default null |
data.production.pitchrequired | object | null | |
data.production.pitch.versionrequired | integer | |
data.production.pitch.verdict | enum | One of: video, skipDefault video |
data.production.pitch.verdictReason | string | null | Default null |
data.production.pitch.titlerequired | string | |
data.production.pitch.summaryrequired | string | |
data.production.pitch.shotsrequired | object[] | |
data.production.pitch.shots[].indexrequired | integer | |
data.production.pitch.shots[].titlerequired | string | |
data.production.pitch.shots[].durationMsrequired | integer | |
data.production.pitch.shots[].beat | string | null | Default null |
data.production.pitch.shots[].visualrequired | string | |
data.production.pitch.shots[].text | string | null | Default null |
data.production.pitch.shots[].voiceover | string | null | Default null |
data.production.pitch.shots[].mediaIds | string[] | |
data.production.pitch.shots[].codePaths | string[] | |
data.production.pitch.music | string | null | Default null |
data.production.pitch.estimatedCreditsrequired | integer | |
data.production.pitch.createdAtrequired | datetime | |
data.production.greenlightrequired | object | null | |
data.production.greenlight.moderequired | enum | One of: manual, auto |
data.production.greenlight.actorrequired | string | |
data.production.greenlight.actorName | string | null | |
data.production.greenlight.atrequired | datetime | |
data.production.greenlight.pitchVersionrequired | integer | |
data.production.greenlightModerequired | enum | One of: manual, auto |
data.production.deliveryrequired | object | null | |
data.production.delivery.shareUrlrequired | url | |
data.production.delivery.projectIdrequired | uuid | |
data.production.delivery.editUrlrequired | url | |
data.production.delivery.exportIdrequired | uuid | |
data.production.delivery.deliveredAtrequired | datetime | |
data.production.projectIdrequired | uuid | null | |
data.production.creditsChargedrequired | integer | |
data.production.errorrequired | string | null | |
data.production.createdAtrequired | datetime | |
data.production.updatedAtrequired | datetime | |
data.production.terminal | boolean | |
data.production.pageUrl | url | |
data.pitchMarkdown | string | null | |
data.status | string | null | |
data.links | object | |
data.links.pagerequired | url | |
data.links.greenlightrequired | url | null | |
data.links.commentrequired | url | null | |
data.links.declinerequired | url | null | |
data.links.sharerequired | url | null | |
data.links.editrequired | url | null | |
data.endpointId | uuid | |
data.message | string |
Your answer
Example
{ "id": "c1d2e3f4-5a6b-4c7d-8e9f-0a1b2c3d4e5f", "type": "production.pitch_ready", "createdAt": "2026-10-17T18:04:12.000Z", "workspaceId": "0b9d8c7a-6e5f-4d3c-ab1a-09f8e7d6c5b4", "data": { "production": { "id": "6f1c2b7e-3d4a-4c8e-9a2b-1f0e5d6c7b8a", "workspaceId": "0b9d8c7a-6e5f-4d3c-ab1a-09f8e7d6c5b4", "stage": "pitch_ready", "source": { "kind": "api", "externalId": "acme/web#412", "origin": { "provider": "github", "label": "acme/web #412", "url": "https://github.com/acme/web/pull/412", "ref": "feat/dark-mode", "requestedBy": "jane" } }, "brief": { "intent": "Announce dark mode in the Acme dashboard to existing customers.", "context": "PR #412 adds a theme toggle to Settings. Charts, tables and the sidebar all pick up the dark palette. Ships to everyone on Thursday.", "media": [ { "id": "dashboard-dark", "kind": "image", "url": "https://cdn.acme.dev/press/dashboard-dark.png", "name": "Dashboard in dark mode", "description": "The analytics overview with the new dark theme." } ], "code": [ { "path": "src/components/settings/theme-toggle.tsx", "source": "", "status": "modified", "additions": 48, "deletions": 9, "patch": null, "sourceOmitted": true, "digest": "ThemeToggle: a pill switch with sun and moon icons, label \"Appearance\", brand purple when on.", "score": 0.91 } ], "format": { "template": "feature", "durationMs": 10000, "aspect": "16:9", "sound": { "voiceover": true, "music": true, "sfx": true } }, "brand": { "name": "Acme", "logoUrl": null, "primaryColor": "#6C5CE7", "backgroundColor": null, "fontFamily": null, "tone": "confident, plain" } }, "pitch": { "version": 1, "verdict": "video", "verdictReason": null, "title": "Dark mode, finally", "summary": "A 10 second feature spot: the toggle flips, the dashboard follows, and an end card says it ships Thursday.", "shots": [ { "index": 0, "title": "The flip", "durationMs": 3000, "beat": "The theme toggle flips and the whole settings page goes dark.", "visual": "The ThemeToggle component rebuilt as layers at hero scale, centred, a slow push-in. On the flip the background sweeps from white to the brand dark.", "text": "Dark mode", "voiceover": "Dark mode is here.", "mediaIds": [], "codePaths": ["src/components/settings/theme-toggle.tsx"] }, { "index": 1, "title": "The dashboard", "durationMs": 4500, "beat": "The analytics overview in dark, tilted, drifting left.", "visual": "dashboard-dark on a device frame, 12 degree tilt, a lateral drift with a soft depth of field.", "text": "Every chart. Every table.", "voiceover": "Charts, tables and the sidebar all follow.", "mediaIds": ["dashboard-dark"], "codePaths": [] }, { "index": 2, "title": "Sign-off", "durationMs": 2500, "beat": "The Acme logo on the dark background with the ship date.", "visual": "Logo centred on the brand dark, the date types on underneath, a short hold before the cut.", "text": "Thursday, for everyone", "voiceover": "Turn it on in Settings, Thursday.", "mediaIds": [], "codePaths": [] } ], "music": "Low, steady, electronic. No drop.", "estimatedCredits": 600, "createdAt": "2026-10-17T18:04:11.000Z" }, "greenlight": null, "greenlightMode": "manual", "delivery": null, "projectId": null, "creditsCharged": 0, "error": null, "createdAt": "2026-10-17T18:02:40.000Z", "updatedAt": "2026-10-17T18:04:11.000Z", "terminal": false, "pageUrl": "https://www.raylight.app/api/productions/6f1c2b7e-3d4a-4c8e-9a2b-1f0e5d6c7b8a" }, "pitchMarkdown": "## Dark mode, finally\n\nA 10 second feature spot ...", "status": null, "links": { "page": "https://www.raylight.app/api/productions/6f1c2b7e-3d4a-4c8e-9a2b-1f0e5d6c7b8a", "greenlight": "https://www.raylight.app/go/v1.eyJqIjoiNmYxYzJiN2UiLCJ2IjoxfQ.q8Zt3VbY1mK0?action=greenlight", "comment": "https://www.raylight.app/go/v1.eyJqIjoiNmYxYzJiN2UiLCJ2IjoxfQ.q8Zt3VbY1mK0?action=comment", "decline": "https://www.raylight.app/go/v1.eyJqIjoiNmYxYzJiN2UiLCJ2IjoxfQ.q8Zt3VbY1mK0?action=decline", "share": null, "edit": null } }}