Webhooks let your backend react to Aurous Labs events without polling. Register an endpoint, subscribe to one or more event types, and we POST a signed payload as soon as the event fires.Documentation Index
Fetch the complete documentation index at: https://mayatech.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Quick start
Register an endpoint
Send a Response (the only time
POST /v1/webhook_endpoints with your HTTPS receiver URL. The response carries a one-time secret — store it; you cannot read it again.secret is non-null):Verify the signature on every delivery
Every delivery carries an
Aurous-Webhook-Signature header of the form t=<unix_sec>,v1=<hex>. Reconstruct the canonical signed payload (${t}.${raw_body}) and HMAC-SHA256 it with your stored secret. See the verifier examples.Aurous Labs uses Unix seconds (a 10-digit timestamp) for the t= parameter, matching the Stripe webhook convention.Return 2xx to acknowledge
Acknowledge within 10 seconds. Any non-2xx, timeout, connection refused, or TLS error counts as a failed delivery and triggers a retry on the exponential-backoff schedule.
Event taxonomy (v1.0)
These eight event types ship in v1.0. Subscribe to a subset via theevents array, or pass ["*"] to subscribe to every type at create time (the wildcard is expanded server-side at create time — new event types added in a later version do NOT auto-subscribe).
| Event type | Fires when |
|---|---|
image.completed | Image generation reached succeeded. Payload contains the rendered URLs. |
image.failed | Image generation failed (provider error, moderation, etc.). |
image.cancelled | Customer called POST /v1/images/:id/cancel. |
video.completed | Video generation reached succeeded. |
video.failed | Video generation failed. |
video.cancelled | Customer cancelled the video generation. |
usage.balance_low | Team credits dropped to or below balance_low_threshold (1h debounced). |
webhook.endpoint_disabled | Another endpoint on this team auto-disabled after sustained failures. |
image.expired, video.expired, image.moderation_rejected, and video.moderation_rejected are planned for v1.1 and not emitted today.
Payload shape
Every delivery body is a single JSON object — the AurousEvent envelope:synthetic: true appears on the envelope (never inside data) when the delivery was triggered via POST /v1/webhook_endpoints/:id/test. Receivers can filter test fires from production traffic with a single field check.
Headers
Every delivery carries the following request headers:| Header | Example | Purpose |
|---|---|---|
Aurous-Webhook-Signature | t=1714867200,v1=8d3f...c4a1 | HMAC-SHA256 of ${t}.${raw_body} with your endpoint secret. Verify on every request. |
Aurous-Event-Id | evt_01HXMQ7Z3K8Y2NABCDEFGHJKMN | Same id as the envelope. Use for de-dup on your side. |
Aurous-Event-Type | image.completed | Same type as the envelope. Lets you route without parsing the body. |
Aurous-Version | 2026-05-15 | API version that minted the event. Add a guard if your handler is version-locked. |
User-Agent | Aurous-Labs-Webhooks/1.0 | Helps you allow-list our traffic at your edge. |
Content-Type | application/json | Always JSON. |
Signature format
Aurous-Webhook-Signature: t=<unix_sec>,v1=<hex>
Where:
<unix_sec>is the moment we minted the signature (a 10-digit Unix timestamp in seconds — the Stripe convention).<hex>is the lowercase hex ofHMAC-SHA256(secret, "${t}.${raw_body}").
t value goes INSIDE the HMAC payload, so an attacker cannot replay a captured body with a tweaked timestamp.
We recommend rejecting any delivery whose t is older than 5 minutes — adjust the tolerance if your receiver uses a lossy queue.
Retries and dead-letter
Failed deliveries (non-2xx, timeout, connect refused, or TLS error) are retried on this schedule:| Attempt | Delay before retry |
|---|---|
| 1 | initial delivery |
| 2 | 5 seconds |
| 3 | 30 seconds |
| 4 | 2 minutes |
| 5 | 10 minutes |
is_terminal: true and the row is flagged with is_dead_letter: true. We stop retrying.
If consecutive_failures >= 20 AND there has been no successful delivery in the last 24 hours, we auto-disable the endpoint:
is_activeflips tofalse.- We email the team owner.
- Other active endpoints on the team receive a
webhook.endpoint_disabledevent so peer integrations can react.
PATCH /v1/webhook_endpoints/:id with { "is_active": true } once you’ve fixed the receiver. The counter resets to 0 on re-enable.
Receiver cookbook
The contract is symmetric: we sign with the active secret only; you verify against the active secret first, then the previous secret as a 24h fallback. This receiver-side fallback is what makes secret rotation zero-downtime.Node.js (Express)
Python (Flask)
Manual curl verification
Useful for one-off debugging: capture a delivery body + signature, then verify locally.Rotating the secret
HitPOST /v1/webhook_endpoints/:id/rotate_secret to mint a new plaintext. The response carries the new secret exactly once.
The contract during rotation:
- Sender (Aurous Labs): signs every new delivery with the active secret only.
- Receiver (you): for the next 24 hours, store the previous secret as
PREVand verify againstACTIVEfirst, then fall back toPREV(as shown in the cookbook).
PREV. We never sign with it again.
Test firing
HitPOST /v1/webhook_endpoints/:id/test with an event_type to enqueue a real, signed synthetic delivery. The envelope carries synthetic: true so receivers can filter test fires from production traffic.
webhooks_test, 30 / minute) so they never contend with normal webhook traffic.
Inspecting deliveries
Walk the per-attempt log viaGET /v1/webhook_endpoints/:id/deliveries:
null for transport errors), error class (http_4xx / http_5xx / timeout / connect_refused / tls_error / connect_error), and the first 1KB of the response body if any. Cursor-paged via ?starting_after=<dlv_id>.