Authentication
- API key is stored in a secret manager, not in source code
- Key rotation procedure is documented and tested
- Old keys are revoked after rotation
Idempotency
- Every
POST /v1/rendersandPOST /v1/tasks/*call includes anIdempotency-Keyheader - Idempotency keys are unique per logical operation (e.g. UUID tied to your internal job ID)
- Retry logic checks for
200(replay) vs202(new job)
Webhooks
- Webhook endpoint is HTTPS with a valid certificate
- HMAC signature verification is implemented (see Signature Verification)
- Webhook handler returns
200within 10 seconds to avoid retry storms - Dead-letter events are monitored and alerted on
Validation
- Compositions are validated with
POST /v1/preview{"dry_run": true}before submitting — it is free, unmetered, and runs the same strict translator the submit path uses, sook: truemeans the render will be accepted -
violations[]entries withseverity: "error"in that dry-run response block the submit in your pipeline;warningfindings are logged and reviewed - The
ok/violations[]that come back on a202fromPOST /v1/renders,POST /v1/projects/{id}/rendersand a201fromPOST /v1/projectsare advisory: that render is already queued and billable. They are your safety net, not your gate — the gate is the free dry-run above. Alert onok: falsethere rather than assuming the submit was refused
Error handling
-
429responses are retried with exponential backoff -
402 quota_exceededis handled distinctly from429— it is a monthly render-time cap, not a rate limit, and must not be retried with backoff -
failedjob status triggers your own alerting -
source_not_found/invalid_sourceerrors surface meaningful messages to your users
Observability
- All Framelane job IDs are logged alongside your internal IDs
- Webhook delivery failures are tracked
- Monthly quota usage is monitored (alert before hitting limits)
Source URLs
- All
source_urlvalues are publicly accessible HTTPS URLs - Source files are under 5 GiB
- Source URLs remain valid for at least 1 hour after job submission (the render engine fetches them asynchronously)

