Skip to content

Share Links

By default the generate endpoint returns raw image bytes. Setting delivery to link publishes the render instead and returns a JSON body carrying a public URL and its expiry.

Useful when the image has to be fetched by something that wants a URL — an <img> tag in a transactional email, a Slack message, a webhook payload, or an automation platform that handles JSON more comfortably than binary.

Add delivery to the generate request body:

FieldTypeDefaultDescription
deliverystringbinarybinary returns raw image/PDF bytes. link publishes the render and returns a JSON share link.

Omitting delivery keeps the existing behaviour exactly — existing integrations need no changes.

Terminal window
curl -X POST https://app.zandovi.com/api/v1/templates/$TEMPLATE_ID/generate \
-H "X-Api-Key: $ZANDOVI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"variables": {
"first_name": "Sarah",
"discount_code": "VIP30"
},
"format": "png",
"delivery": "link"
}'
{
"id": "019a4c31-8e2f-7b10-9c44-1d5e77b0a913",
"url": "https://img.zandovi.com/s/8f3c2ad9e1b74c05.png",
"templateId": "019463b8-1234-7890-abcd-ef1234567890",
"templateName": "Autumn voucher",
"mimeType": "image/png",
"fileSize": 41982,
"source": "API",
"createdAt": "2026-08-24T09:00:00Z",
"expiresAt": "2026-09-23T09:00:00Z"
}

The X-Request-Id, X-Template-Id, and X-Timestamp response headers are returned as usual.

FieldTypeDescription
idUUIDIdentifier for the link — pass it to the revoke endpoint
urlstringThe public URL. Serve it directly; it needs no auth
templateIdUUID | nullTemplate the render came from
templateNamestring | nullTemplate name captured at share time — survives the template being deleted later
mimeTypestringimage/png, image/jpeg, image/webp, or application/pdf
fileSizeintegerSize of the published object, in bytes
sourcestringAPI for links created with a key, DESIGNER for links created in the app
createdAtstringISO 8601 UTC
expiresAtstringISO 8601 UTC — after this the object is deleted and the URL stops resolving

Store expiresAt alongside whatever references the URL. When it lapses there is nothing to renew — generate the image again and share the new result.

GET /api/v1/shares
Query parameterDefaultDescription
page0Zero-based page index
size20Items per page

Returns the links created with this API key’s account, newest first. Ordering is stable across pages.

Terminal window
curl https://app.zandovi.com/api/v1/shares?page=0&size=20 \
-H "X-Api-Key: $ZANDOVI_API_KEY"
{
"data": [ /* share link objects, as above */ ],
"pagination": { "page": 0, "size": 20, "totalElements": 143, "totalPages": 8 }
}

There is no history view. An expired link stays listed only until the next cleanup pass removes it.

DELETE /api/v1/shares/{shareId}

Deletes the published object and its record, so the URL stops resolving. Responds 204 No Content.

Terminal window
curl -X DELETE https://app.zandovi.com/api/v1/shares/$SHARE_ID \
-H "X-Api-Key: $ZANDOVI_API_KEY"

Revocation is permanent — there is no undo, and the link cannot be restored. Published images are cached at the edge for up to five minutes; revoking purges that cache, but a copy may still be served briefly.

An API key can only see and revoke the links its own account created. Any other link in the organization responds 404, the same as a link that doesn’t exist.

This differs from the app, where a workspace Owner or Admin can manage every link in the organization. Revoking or deleting an API key does not revoke the links created with it.

StatuscodeCause
403SHARING_NOT_AVAILABLE_ON_PLANThe organization’s plan does not include share links
403SHARE_LINK_LIMIT_REACHEDThe organization is at its cap of active links — revoke one or upgrade
404SHARE_NOT_FOUNDNo such link, or it belongs to another account
502SHARE_UPLOAD_FAILEDThe render succeeded but could not be published — nothing was created, safe to retry
502SHARE_REVOKE_FAILEDThe object could not be deleted — the link may still resolve, retry
503SHARING_UNAVAILABLEShare storage is temporarily unavailable

A SHARE_UPLOAD_FAILED leaves nothing behind, so retrying is safe — but it re-renders and consumes another render. If you need the bytes regardless, retry with delivery: "binary".

See Errors, quotas & rate limits for the response body format and general retry guidance.

Retention (how long a link lives) and the cap on simultaneously active links both vary by plan. Current values are on the Zandovi pricing page and the Plans page in the app.

The active-link cap is checked when a link is created. If a plan change leaves you above the cap, existing links keep working — you just can’t create new ones until you’re back under it.

Share links are temporary hosting. They’re the wrong tool when the image has to persist:

  • Anything referenced from a long-lived page — OG images in a page’s <head>, product imagery, avatars. Use delivery: "binary" and store the bytes yourself.
  • Anything that must be private. There is no per-viewer access control.
  • Anything needing custom cache or CORS headers. The published objects use fixed headers.