Skip to main content
POST /api/v1/facade/generate can render two ways, chosen by operation: This guide covers the async path.

Step 1 — submit the job

Submit a normal generate request with "operation": "render":
Response — HTTP 202, immediately, before rendering:

Step 2A — subscribe to webhooks (preferred)

Register a webhook once and Kynva delivers a render.completed (or render.failed) event when any of your jobs finishes — no polling at all:
See the webhooks overview for signatures, retries, and the delivery contract.

Step 2B — poll for status

While the job runs, the response also carries progress detail:
  • status is the coarse lifecycle: queued → processing → completed | failed.
  • stage is the granular pipeline step while processing (QUEUED, ASSET_DOWNLOADING, ASSET_READY, RENDERING_SCENES, UPLOADING, COMPLETING) — useful for progress UIs.
Polls count against the jobs:status rate-limit bucket (60/min on the free tier). Back off as shown above — or use webhooks and don’t poll at all.

Step 2C — live progress over SSE

For a progress bar without polling, open the server-sent-events stream:
Events: job_status (progress updates), job_complete, job_failed. The stream times out after 5 minutes; the poll endpoint above is the durable fallback.

Step 3 — fetch the results

Once status is "completed", outputs holds the rendered files:
Output URLs are stable, long-lived CDN URLs (served with Cache-Control: immutable) — safe to store and hot-link. Because rendering is deterministic, the same job re-run from the same request produces the same bytes.

How long is job status available?

Store design_id if you want a permanent handle — the design (and its outputs) outlives the job record.