This reference documents every webhook and callback that Templified sends to your server: the render-complete callback fired per render job, the Studio export notification for org-scoped destinations, and the batch-complete callback for Design Group renders.
Two distinct webhook types
Templified sends two different kinds of outbound webhook, and they serve different purposes:
-
Render-complete callback — attached to a single render job at submission time via the
webhook_urlparameter onPOST /api/v1/createorPOST /api/v1/design-groups/create. Fires once when that specific job finishes. -
Studio export notification — org-scoped. Every time a design is exported from Studio (or sent via
send_to: "integration:webhook"), Templified posts the samestudio.exportnotification body to the single URL configured in Settings → Integrations → Webhook.
Both types require an HTTPS endpoint. Both retry up to three times with increasing delays if your server does not respond with a 2xx status within 10 seconds. See the setup guide Setting up the Studio export webhook for how to configure the org-scoped URL and HMAC signing.
Render-complete callback body
When a render job you submitted with webhook_url finishes, Templified sends POST <your_url> with Content-Type: application/json. The body contains the following fields:
| Field | Type | Description |
|---|---|---|
job_id |
string | The render job identifier, matching the job_id from the 202 submission response. |
status |
string |
"complete" or "failed". |
template_id |
string | ID of the template that was rendered. |
output_url |
string or null | Public URL of the finished image. Present when status is "complete"; null on failure. |
render_ms |
number or null | Wall-clock render time in milliseconds. Absent on failure. |
completed_at |
ISO 8601 string or null | Timestamp when the job finished. |
instance_id |
string | Present only when the render was tied to a Studio design. Omitted for pure API renders with no design counterpart. |
player_id |
string | Present only when player_id was supplied at submission time. |
Example
{
"job_id": "clxw3r2e40000abc123",
"status": "complete",
"template_id": "tmpl_abc",
"output_url": "https://cdn.templified.io/renders/org_x/clxw3.jpg",
"render_ms": 3820,
"completed_at": "2026-06-12T14:05:32.000Z",
"instance_id": "inst_xyz",
"player_id": "24"
}
Retries and failure handling
Templified attempts delivery up to three times. The backoff delays between attempts are approximately 5 seconds, then 30 seconds, then 2 minutes. Every attempt is recorded in your account's delivery log. If all three attempts fail, the job's webhook status is marked "failed" — the render itself still completed (or failed) normally and the result remains available via GET /api/v1/create/:job_id.
Your server must respond with any 2xx HTTP status within 10 seconds. Respond quickly — do any long-running work asynchronously after acknowledging receipt.
Studio export notification (studio.export)
The org-scoped webhook fires whenever a design is sent from Studio or when a render submitted via the API includes "send_to": "integration:webhook". The body is always a studio.export event.
| Field | Type | Description |
|---|---|---|
event |
string | Always "studio.export". |
exportedAt |
ISO 8601 string | Timestamp when the export was triggered. |
orgId |
string | Your organization identifier. |
instanceId |
string or null | The design ID in Studio, or null when the render was submitted directly via POST /api/v1/create with send_to: "integration:webhook" and had no Studio design. Receivers that key on instanceId must guard for null. |
templateId |
string | ID of the template the design is based on. |
designName |
string | The name of the design as it appears in Studio. |
folder |
string | The Studio folder that contains the design. |
imageUrl |
string | Public URL of the finished render image. |
qty |
number (optional) | Number of copies requested. Omitted when the quantity is 1 (the default). Receivers can use this to loop a downstream action — for example, send to a print destination N times — without Templified firing the webhook more than once per export. |
mainEventCode |
string or null (optional) | Main event code set on the design, if any. |
destinationEventCode |
string or null (optional) | Destination event code set on the design, if any. |
playerId |
string or null (optional) | Player identifier carried from the design or render, if present. |
textLayers |
array | One object per text layer: { "name": "…", "content": "…" }. The layer's name and its resolved text value at the time of export. |
Example
{
"event": "studio.export",
"exportedAt": "2026-06-12T14:10:00.000Z",
"orgId": "org_abc",
"instanceId": "inst_xyz",
"templateId": "tmpl_abc",
"designName": "Smith, Jordan — 5x7",
"folder": "Fall 2026",
"imageUrl": "https://cdn.templified.io/renders/org_abc/inst_xyz.jpg",
"qty": 2,
"mainEventCode": "1373",
"destinationEventCode": "042",
"playerId": "12",
"textLayers": [
{ "name": "Player Name", "content": "Jordan Smith" },
{ "name": "Team", "content": "Westside Warriors" }
]
}
HMAC signature
If you configured an HMAC secret in Settings → Integrations → Webhook, every delivery includes an X-Templified-Signature header in the format sha256=<hex>. Compute HMAC-SHA256 of the raw request body using your secret and compare it to the header value to verify the request came from Templified.
Design Groups: one batch-complete callback per batch
When you submit a Design Group batch render via POST /api/v1/design-groups/create, you can supply two separate webhook URLs:
-
webhook_url— called once per individual render job as each template in the group finishes. The body shape matches the render-complete callback described above. -
batch_webhook_url— called exactly once when every render in the batch has reached a terminal state (all complete or failed). The body mirrors theGET /api/v1/design-groups/create/:batch_idpoll response, giving you the full batch summary in a single signal.
The batch-complete callback fires regardless of individual job outcomes — it signals that the batch is done, not that every job succeeded. Check each job's status in the batch summary to determine which renders completed and which did not.
Both webhook_url and batch_webhook_url are optional and independent. You can supply one, both, or neither.
Polling as an alternative to webhooks
If you cannot expose a public HTTPS endpoint, poll for results instead:
- Single render:
GET /api/v1/create/:job_id - Design Group batch:
GET /api/v1/design-groups/create/:batch_id
Both endpoints return the current status and, once complete, the same output fields you would receive via webhook. Polling and webhook callbacks are independent — you can use either or both on the same job.
Comments
0 comments
Article is closed for comments.