Browse the docs Open Close
API Reference
every object, every endpoint
The complete reference, generated from the live API spec. Download it whole as Markdown, OpenAPI or Postman.
Objects
Template
A reusable design with addressable layers.
| Field | Type | Description |
|---|---|---|
uuid |
string | Stable public identifier. |
title |
string | Human-readable name. |
width |
integer | Canvas width in pixels. |
height |
integer | Canvas height in pixels. |
layers |
Layer[] | Addressable layers and their modifications. |
created_at |
datetime | ISO-8601 creation timestamp. |
Layer
A single addressable element inside a template.
| Field | Type | Description |
|---|---|---|
layer |
string | Layer key used when overriding content. |
type |
string | One of image, text, empty, qr_code, barcode. |
available_modifications |
object | Override keys this layer accepts (image_url, text, background_color, qr_content, barcode_content). |
Screenshot
A rendered capture of a web page.
| Field | Type | Description |
|---|---|---|
id |
string | Screenshot UUID. |
url |
string | Captured page URL. |
image_url |
string | URL of the rendered image. |
width |
integer | Viewport width in pixels. |
height |
integer | Viewport height in pixels. |
created_at |
datetime | ISO-8601 creation timestamp. |
Snap
A render job produced from a template or collection.
| Field | Type | Description |
|---|---|---|
id |
string | Snap UUID. |
media_url |
string|null | URL of the finished asset, null until completed. |
type |
string | image or pdf. |
status |
string | pending, processing, completed, failed or canceled. |
is_async |
boolean | Whether the snap was queued. |
webhook_url |
string|null | Callback URL for async completion. |
completed_at |
datetime|null | When rendering finished. |
last_error |
string|null | Failure reason, when status is failed. |
variants |
array|null | Per-layer content overrides applied. |
template_id |
string|null | Source template UUID. |
template_title |
string|null | Source template name. |
created_at |
datetime | ISO-8601 creation timestamp. |
Endpoints
Authentication
/v1/auth
Verify the current token
Returns the account the token belongs to. Use it to confirm a token is valid and to read the signed-in identity.
Example request
curl
curl https://snapsbrew.com/api/v1/auth \
-H 'Authorization: Bearer <your-token>' \
-H 'Accept: application/json'
Example responses
{
"data": {
"email": "[email protected]",
"name": "Ada Lovelace"
}
}
{
"message": "Unauthenticated."
}
{
"message": "Invalid ability provided."
}
Usage
/v1/usage
Get current usage
Returns purchased, used and remaining requests for the active billing period.
The response carries an `X-Request-Uuid` header you can quote in support tickets.
Example request
curl
curl https://snapsbrew.com/api/v1/usage \
-H 'Authorization: Bearer <your-token>' \
-H 'Accept: application/json'
Example responses
{
"period_start_date": "2026-05-01T00:00:00Z",
"period_end_date": "2026-05-31T23:59:59Z",
"period_purchased_requests": 1000,
"period_used_requests": 240,
"period_available_requests": 760
}
{
"message": "Unauthenticated."
}
Templates
/v1/templates
List templates
Returns a cursor-paginated list of your templates.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | Cursor token from a previous response's meta.next_cursor. |
Example request
curl
curl https://snapsbrew.com/api/v1/templates \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"data": [
{
"uuid": "141e8454-8aa1-420a-bd0b-18a85ba949a2",
"title": "Template 1",
"width": 1200,
"height": 630,
"layers": [
{
"layer": "review_title",
"type": "text",
"available_modifications": {
"text": "The worst Time-Travel movie ever made"
}
}
],
"created_at": "2026-05-01T12:00:00Z"
}
],
"meta": {
"previous_cursor": null,
"next_cursor": "eyJpZCI6MTB9"
}
}
/v1/templates/sizes
List canvas size presets
Returns every canvas size preset a template write accepts as `size` — Instagram, Facebook, X, LinkedIn, Threads, Pinterest, TikTok, YouTube, Snapchat, WhatsApp, web and email, display ads, and print. Each preset gives its dimensions, aspect ratio, and the safe margin to keep content away from the edges.
Example request
curl
curl https://snapsbrew.com/api/v1/templates/sizes \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"data": [
{
"size": "instagram_story",
"name": "Instagram Story (1080x1920)",
"platform": "Instagram",
"width": 1080,
"height": 1920,
"aspect_ratio": "9:16",
"safe_margin_px": 97
},
{
"size": "open_graph",
"name": "Open Graph / Link Preview (1200x630)",
"platform": "Web & email",
"width": 1200,
"height": 630,
"aspect_ratio": "1.9:1",
"safe_margin_px": 47
}
]
}
/v1/templates/{templateUuid}
Get a template
Returns a single template and its parsed layers.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
templateUuid |
path | string | Yes | UUID of the template. |
Example request
curl
curl https://snapsbrew.com/api/v1/templates/<uuid> \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"uuid": "141e8454-8aa1-420a-bd0b-18a85ba949a2",
"title": "Template 1",
"width": 1200,
"height": 630,
"layers": [
{
"layer": "review_poster",
"type": "image",
"available_modifications": {
"image_url": "https://snapsbrew.com/crazy-doc-brown-jailed"
}
},
{
"layer": "review_title",
"type": "text",
"available_modifications": {
"text": "The worst Time-Travel movie ever made"
}
}
],
"created_at": "2026-05-01T12:00:00Z"
}
{
"message": "Not found."
}
/v1/templates
Create a template
Creates a template and generates its preview image. Requires the create-template policy.
Request body
Content-Type: application/json
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
title |
string | Yes | required|string|max:255 |
Template name. |
size |
string | No | nullable|in:<preset> |
Canvas size preset, for example "instagram_story" or "youtube_thumbnail". It sets width and height for you. GET /v1/templates/sizes lists every preset. |
width |
integer | No | nullable|numeric|min:1|max:4000 |
Canvas width in pixels. Ignored when you send a size preset. |
height |
integer | No | nullable|numeric|min:1|max:4000 |
Canvas height in pixels. Ignored when you send a size preset. |
layers |
array | No | nullable|array |
Layer definitions; stored JSON-encoded. |
Send a `size` preset or an explicit `width`/`height`. A template saved with dimensions that match a preset is stored under that preset.
Example request
curl
curl -X POST https://snapsbrew.com/api/v1/templates \
-H 'Authorization: Bearer <your-token>' \
-H 'Content-Type: application/json' \
-d '{"title":"Launch card","size":"open_graph","layers":[]}'
Example responses
{
"data": {
"uuid": "...",
"title": "New template"
},
"message": "Template created successfully"
}
/v1/templates/{templateId}
Update a template
Updates a template and regenerates its preview image. The path segment is the numeric template ID, not the UUID.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
templateId |
path | integer | Yes | Numeric template ID, scoped to your company. |
Request body
Content-Type: application/json
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
title |
string | Yes | required|string|max:255 |
Template name. |
size |
string | No | nullable|in:<preset> |
Canvas size preset, for example "instagram_story" or "youtube_thumbnail". It sets width and height for you. GET /v1/templates/sizes lists every preset. |
width |
integer | No | nullable|numeric|min:1|max:4000 |
Canvas width in pixels. Ignored when you send a size preset. |
height |
integer | No | nullable|numeric|min:1|max:4000 |
Canvas height in pixels. Ignored when you send a size preset. |
layers |
array | No | nullable|array |
Layer definitions; stored JSON-encoded. |
Example request
curl
curl -X PATCH https://snapsbrew.com/api/v1/templates/42 \
-H 'Authorization: Bearer <your-token>' \
-H 'Content-Type: application/json' \
-d '{"title":"Updated title"}'
Example responses
{
"message": "template updated sucessfully"
}
{
"message": "Not found."
}
/v1/templates/{templateId}
Delete a template
Deletes a template. The path segment is the numeric template ID. Requires the delete-template policy.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
templateId |
path | integer | Yes | Numeric template ID, scoped to your company. |
Example request
curl
curl -X DELETE https://snapsbrew.com/api/v1/templates/42 \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"message": "template deleted sucessfully"
}
{
"message": "Not found."
}
Media
/v1/media
List media
Returns your uploaded images, 12 per page, newest first.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page |
query | integer | No | Page number for the standard paginator. |
Example request
curl
curl https://snapsbrew.com/api/v1/media \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"data": [
{
"id": 12,
"file_name": "logo.png",
"src": "https://snapsbrew.com/storage/12/conversions/logo-image.jpg"
}
],
"links": {
"first": "...",
"last": "...",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"per_page": 12,
"total": 1
}
}
/v1/media
Upload media
Uploads an image into your media library. Send as multipart/form-data.
Request body
Content-Type: multipart/form-data
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
file |
file | Yes | required, file, image |
The image to upload. |
Example request
curl
curl -X POST https://snapsbrew.com/api/v1/media \
-H 'Authorization: Bearer <your-token>' \
-F '[email protected]'
Example responses
{
"id": 12,
"file_name": "logo.png",
"src": "https://snapsbrew.com/storage/12/conversions/logo-image.jpg"
}
{
"message": "The file must be an image."
}
Screenshots
/v1/screenshots
List screenshots
Returns a cursor-paginated list of your screenshots.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
cursor |
query | string | No | Cursor token from meta.next_cursor. |
Example request
curl
curl https://snapsbrew.com/api/v1/screenshots \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"data": [
{
"uuid": "a1b2c3",
"url": "https://example.com",
"image_url": "https://snapsbrew.com/storage/screenshots/a1b2c3.png",
"width": 1330,
"height": 780,
"created_at": "2026-05-01T12:00:00Z"
}
],
"meta": {
"previous_cursor": null,
"next_cursor": null
}
}
/v1/screenshots/{screenshotUuid}
Get a screenshot
Returns a single screenshot.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
screenshotUuid |
path | string | Yes | UUID of the screenshot. |
Example request
curl
curl https://snapsbrew.com/api/v1/screenshots/<uuid> \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"data": {
"id": "a1b2c3",
"url": "https://example.com",
"image_url": "https://snapsbrew.com/storage/screenshots/a1b2c3.png",
"width": 1330,
"height": 780,
"created_at": "2026-05-01T12:00:00Z"
}
}
{
"message": "Not found."
}
/v1/screenshots
Create a screenshot
Captures a web page. Defaults to a 1330x780 viewport when width/height are omitted.
Credits — Requires available credits (canCreateSnap); returns 417 when exhausted.
Request body
Content-Type: application/json
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
url |
string | No | url |
Page to capture. Validated as a URL when present. |
width |
integer | No | integer |
Viewport width. Defaults to 1330. |
height |
integer | No | integer |
Viewport height. Defaults to 780. |
Example request
curl
curl -X POST https://snapsbrew.com/api/v1/screenshots \
-H 'Authorization: Bearer <your-token>' \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com","width":1330,"height":780}'
Example responses
{
"data": {
"id": "a1b2c3",
"url": "https://example.com",
"image_url": "https://snapsbrew.com/storage/screenshots/a1b2c3.png",
"width": 1330,
"height": 780,
"created_at": "2026-05-01T12:00:00Z"
}
}
{
"message": "Unauthenticated."
}
{
"message": "You have reached your snap quota."
}
Snaps
/v1/snaps
Create a snap
Renders a snap from a single template (`template_id`) or every template in a collection (`collection_id`). Provide exactly one of the two.
Synchronous (default): the response carries the finished `media_url` and returns 201.
Asynchronous (`async: true`): the snap is queued, the response returns 202 immediately, and the result is delivered to `webhook_url` on completion.
The API always renders the template's **published** version. Unpublished draft edits are not visible to the API until the template is published.
Credits — Synchronous: 1 credit per rendered template. Asynchronous: 0 credits at accept time (HTTP 202); the credit is charged when the queued snap reaches completed. A repeated `idempotency_key` returns the first snap and charges 0 credits.
Request body
Content-Type: application/json
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
template_id |
string | No | required_without:collection_id, prohibits:collection_id, exists templates.uuid scoped to company |
UUID of a single template to render. |
collection_id |
string | No | required_without:template_id, prohibits:template_id, exists template_collections.uuid scoped to company |
UUID of a collection; one snap is rendered per template. |
type |
string | No | nullable, in:image,pdf |
Output type. Defaults to image. |
format |
string | No | sometimes, in:png,jpeg,webp |
Image output format (image type only). Defaults to png. |
transparent |
boolean | No | sometimes, boolean; rejected with png-only/webp-only — 422 when combined with format=jpeg |
Render on a transparent background. Valid for png and webp only; jpeg + transparent returns 422. |
async |
boolean | No | sometimes, boolean |
Queue the render and return 202. |
webhook_url |
string | No | url, required_if:async,true, must be a public http or https address |
Callback URL invoked when an async snap completes. The address must be public. A host that resolves to a private, loopback, link-local or reserved range is rejected with 422. |
variants |
array | No | no server validation |
Per-layer content overrides applied to the render. |
idempotency_key |
string | No | sometimes, nullable, string, max:191, letters/digits/underscore/hyphen only, prohibits:collection_id |
Send the same key when you retry after a timeout. The retry returns the same snap and charges no second credit. Keys are honored for 24 hours and are scoped to your account. Not supported with collection_id. |
Every response carries an `X-Request-Uuid` header. Quote it in support tickets.
A collection request returns an array of snap objects, one per template.
A response to a repeated `idempotency_key` carries an `X-Idempotent-Replay: true` header and charges 0 credits.
`webhook_url` must be a public address. A host that resolves to a private, loopback, link-local or reserved range is rejected with 422.
An `idempotency_key` is honored for 24 hours. After that window a retry is a new request and charges a new credit.
Example request
curl
curl -X POST https://snapsbrew.com/api/v1/snaps \
-H 'Authorization: Bearer <your-token>' \
-H 'Content-Type: application/json' \
-d '{"template_id":"<uuid>","type":"image","variants":[{"layer":"review_title","text":"Hello world"}]}'
async curl
curl -X POST https://snapsbrew.com/api/v1/snaps \
-H 'Authorization: Bearer <your-token>' \
-H 'Content-Type: application/json' \
-d '{"template_id":"<uuid>","async":true,"webhook_url":"https://example.com/hooks/snap"}'
Example responses
{
"id": "9f1c2d3e",
"media_url": "https://snapsbrew.com/storage/snaps/9f1c2d3e.png",
"type": "image",
"status": "completed",
"is_async": false,
"webhook_url": null,
"completed_at": "2026-05-01T12:00:03Z",
"last_error": null,
"variants": [],
"template_id": "141e8454-8aa1-420a-bd0b-18a85ba949a2",
"template_title": "Launch card",
"created_at": "2026-05-01T12:00:00Z"
}
{
"id": "9f1c2d3e",
"media_url": null,
"type": "image",
"status": "pending",
"is_async": true,
"webhook_url": "https://example.com/hooks/snap",
"completed_at": null,
"last_error": null,
"variants": [],
"template_id": "141e8454-8aa1-420a-bd0b-18a85ba949a2",
"template_title": "Launch card",
"created_at": "2026-05-01T12:00:00Z"
}
{
"message": "Not found."
}
{
"message": "You have reached your snap quota."
}
{
"message": "A request with this idempotency_key is already in progress. Retry in a moment. Nothing was created and nothing was charged."
}
{
"message": "The template id field is required when collection id is not present."
}
Snap batches
/v1/snaps/batches
Create a batch of snaps
Renders up to 100 snaps from one template. Every item carries its own `variants` and an optional `identifier` you use to recognize it in the result.
The response is always 202. Nothing is charged at accept time. Each item costs 1 credit when it renders.
`type`, `format` and `transparent` apply to every item in the batch. An item that needs a different format belongs in a different batch.
The API always renders the template's **published** version.
Credits — 0 credits at accept time (HTTP 202). Each item is charged 1 credit when it reaches completed. An item that fails costs nothing. A repeated `idempotency_key` returns the first batch and starts no second one.
Request body
Content-Type: application/json
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
template_id |
string | Yes | required, exists templates.uuid scoped to company |
UUID of the template every item renders from. |
items |
array | Yes | required, array, min:1, max:100 |
One entry per snap. Over 100 entries returns 422 and creates nothing. |
items[].variants |
array | No | each image_url must be a public http or https address |
Per-layer content overrides for this item. |
items[].identifier |
string | No | sometimes, nullable, string, max:191 |
Your own name for this item. Defaults to item_1, item_2, and so on. |
title |
string | No | sometimes, string, max:255 |
A name for the batch, shown in the account. Defaults to "API batch". |
webhook_url |
string | No | nullable, url, max:2048, must be a public http or https address |
ONE request is posted to this address when the batch finishes. A host that resolves to a private, loopback, link-local or reserved range is rejected with 422. |
type |
string | No | sometimes, in:image,pdf |
Output type for every item. Defaults to image. |
format |
string | No | sometimes, in:png,jpeg,webp |
Image output format for every item. Defaults to png. |
transparent |
boolean | No | sometimes, boolean; 422 when combined with format=jpeg |
Render every item on a transparent background. Valid for png and webp only. |
idempotency_key |
string | No | sometimes, nullable, string, max:191, letters/digits/underscore/hyphen only |
Send the same key when you retry after a timeout. The retry returns the same batch and starts no second one. Keys are honored for 24 hours and are scoped to your account. A key already used by POST /v1/snaps returns 409. |
The whole batch is checked against the credit balance before any item is created. A batch of 100 against 40 credits creates nothing, not 40 items.
The balance check is not a reservation. Two batches accepted a second apart read the same balance, so a caller can queue more items than the balance covers. Each item is still charged only when it renders.
Over 100 items returns 422 on `errors.items` and creates nothing. The request is never truncated in silence.
Exactly one webhook is posted, when the batch finishes. There is no per-item webhook on this endpoint.
`webhook_url` must be a public address. A host that resolves to a private, loopback, link-local or reserved range is rejected with 422.
A response to a repeated `idempotency_key` carries an `X-Idempotent-Replay: true` header.
Every response carries an `X-Request-Uuid` header. Quote it in support tickets.
A batch holds one of five statuses. `pending` and `processing` mean it is still running. The three terminal statuses are `completed`, `failed` and `canceled`, and a batch never leaves one. `completed` means the batch ran to the end and at least one item rendered, so read the `failed` count as well as the status. `failed` means zero items rendered. At every terminal status `completed + failed + canceled` equals `total_rows`.
Example request
curl
curl -X POST https://snapsbrew.com/api/v1/snaps/batches \
-H 'Authorization: Bearer <your-token>' \
-H 'Content-Type: application/json' \
-d '{"template_id":"<uuid>","title":"October launch","items":[{"identifier":"row-1","variants":[{"layer":"headline","text":"Hello"}]},{"identifier":"row-2","variants":[{"layer":"headline","text":"World"}]}]}'
Example responses
{
"uuid": "7c1f2a9e-0b44-4a1e-9f2b-5d3c8e1a7b60",
"title": "October launch",
"status": "processing",
"total_rows": 3,
"processed_rows": 0,
"completed": 0,
"pending": 3,
"failed": 0,
"canceled": 0,
"credits_charged": 0,
"status_url": "https://snapsbrew.com/api/v1/snaps/batches/7c1f2a9e-0b44-4a1e-9f2b-5d3c8e1a7b60"
}
{
"message": "This idempotency_key already belongs to a single snap. Use a new key for a batch."
}
{
"message": "You have reached your snap quota."
}
{
"message": "A batch accepts at most 100 items. Split the request into smaller batches."
}
/v1/snaps/batches/{batchUuid}
Read a batch
Returns the counts, the running credit total, and every item with its status and image URL. Poll this about every 5 seconds and stop when `status` is `completed`, `failed` or `canceled`.
This endpoint does not require an active subscription, so a customer whose plan lapsed can still collect work they already paid for.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batchUuid |
path | string | Yes | The batch id returned by POST /v1/snaps/batches. |
A batch holds one of five statuses. `pending` and `processing` mean it is still running. The three terminal statuses are `completed`, `failed` and `canceled`, and a batch never leaves one. `completed` means the batch ran to the end and at least one item rendered, so read the `failed` count as well as the status. `failed` means zero items rendered. At every terminal status `completed + failed + canceled` equals `total_rows`.
`credits_charged` is read from the billing ledger, not counted from `completed`. It rises between polls.
`media_url` is set only on an item with status `completed`.
`last_error` on a failed item carries the render error as the renderer reported it. Treat it as a message for a person, never as a stable code to branch on.
A batch id that belongs to another account returns 404, the same as an id that does not exist.
Example request
curl
curl 'https://snapsbrew.com/api/v1/snaps/batches/<batch-uuid>' \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"uuid": "7c1f2a9e-0b44-4a1e-9f2b-5d3c8e1a7b60",
"title": "October launch",
"status": "completed",
"total_rows": 2,
"processed_rows": 2,
"completed": 1,
"pending": 0,
"failed": 1,
"canceled": 0,
"credits_charged": 1,
"status_url": "https://snapsbrew.com/api/v1/snaps/batches/7c1f2a9e-0b44-4a1e-9f2b-5d3c8e1a7b60",
"items": [
{
"id": "9f1c2d3e",
"identifier": "row-1",
"status": "completed",
"media_url": "https://snapsbrew.com/storage/snaps/9f1c2d3e.png",
"last_error": null
},
{
"id": "4b8a7c6d",
"identifier": "row-2",
"status": "failed",
"media_url": null,
"last_error": "Render failed."
}
]
}
{
"message": "No batch with that id exists in your account."
}
/v1/snaps/batches/{batchUuid}/cancel
Cancel a batch
Stops a batch that is still running.
An item that already rendered keeps its image and stays billed. An item that had not started is marked `canceled` and costs nothing. An item that is rendering at that moment can still finish and can still be charged.
This cannot be undone. A canceled batch cannot be resumed. Start a new batch for the items you still want.
Like the read endpoint, this does not require an active subscription: stopping work only lowers the bill.
Credits — Nothing is charged by this call. Items that already rendered keep the credit they cost. Items that never started cost nothing.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batchUuid |
path | string | Yes | The batch id returned by POST /v1/snaps/batches. |
Canceling twice is safe. A batch that already holds a terminal status is returned unchanged.
One webhook is posted, carrying `event: snap-import.canceled`.
An item that is rendering when the cancel lands can still complete and can still be charged. The counts in the response are the truth at that moment.
A batch id that belongs to another account returns 404, the same as an id that does not exist.
Example request
curl
curl -X POST 'https://snapsbrew.com/api/v1/snaps/batches/<batch-uuid>/cancel' \
-H 'Authorization: Bearer <your-token>'
Example responses
{
"uuid": "7c1f2a9e-0b44-4a1e-9f2b-5d3c8e1a7b60",
"title": "October launch",
"status": "canceled",
"total_rows": 3,
"processed_rows": 3,
"completed": 1,
"pending": 0,
"failed": 0,
"canceled": 2,
"credits_charged": 1,
"status_url": "https://snapsbrew.com/api/v1/snaps/batches/7c1f2a9e-0b44-4a1e-9f2b-5d3c8e1a7b60",
"items": [
{
"id": "9f1c2d3e",
"identifier": "row-1",
"status": "completed",
"media_url": "https://snapsbrew.com/storage/snaps/9f1c2d3e.png",
"last_error": null
},
{
"id": "4b8a7c6d",
"identifier": "row-2",
"status": "canceled",
"media_url": null,
"last_error": null
},
{
"id": "2e5f9a1b",
"identifier": "row-3",
"status": "canceled",
"media_url": null,
"last_error": null
}
]
}
{
"message": "No batch with that id exists in your account."
}
Preview
/v1/templates/{templateUuid}/preview
Preview a template
Renders a free, watermarked preview of a template using its default layer content, or with `variants` applied. Returns a self-contained HTML document (text/html).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
templateUuid |
path | string | Yes | UUID of the template to preview. |
variants |
query | array | No | Per-layer overrides, e.g. variants[0][layer]=headline&variants[0][text]=Hello. Each item targets a layer key with one of text, image_url (public URL), background_color, qr_content, barcode_content, or hidden. |
The preview is watermarked HTML, not a usable final asset.
No credit is charged and no snap is stored.
Example request
curl
curl 'https://snapsbrew.com/api/v1/templates/<uuid>/preview' \
-H 'Authorization: Bearer <your-token>' \
--output preview.html
Example responses
"<!DOCTYPE html>\u2026watermarked preview\u2026</html>"
{
"message": "Not found."
}
{
"message": "The variants.0.image_url must be a public http or https URL."
}
{
"message": "Too Many Attempts."
}
/v1/snaps/preview
Preview a snap
Renders a free, watermarked preview of the snap you intend to create — a template (`template_id`) plus `variants`. Returns a self-contained HTML document (text/html). Pass the same template_id and variants to POST /v1/snaps to create the final billed snap.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
template_id |
query | string | Yes | UUID of the template to render. |
variants |
query | array | No | Per-layer overrides, e.g. variants[0][layer]=headline&variants[0][text]=Hello. Each item targets a layer key with one of text, image_url (public URL), background_color, qr_content, barcode_content, or hidden. |
The preview is watermarked HTML, not a usable final asset.
No credit is charged and no snap is stored.
Example request
curl
curl 'https://snapsbrew.com/api/v1/snaps/preview?template_id=<uuid>&variants[0][layer]=headline&variants[0][text]=Hello' \
-H 'Authorization: Bearer <your-token>' \
--output preview.html
Example responses
"<!DOCTYPE html>\u2026watermarked preview\u2026</html>"
{
"message": "Not found."
}
{
"message": "The template id field is required."
}
{
"message": "Too Many Attempts."
}
Tags
Embedded Forms
/v1/embedded-forms/{formUuid}
Submit an embedded form
Renders a snap from a configured form. Template forms return one snap; collection forms return an array of snaps.
Layer keys: template forms use the plain layer key (`headline`); collection forms use `{templateUuid}__{layerKey}`. Only layers the form was configured with are accepted; the rest are dropped silently.
Credits — The form owner is charged: 1 credit for a template form, or 1 per template for a collection form.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
formUuid |
path | string | Yes | UUID of the form. |
signature |
query | string | Yes | Laravel URL signature. The whole URL must be signed. |
Request body
Content-Type: multipart/form-data
| Field | Type | Required | Validation | Description |
|---|---|---|---|---|
layers |
object | No | keys matched against the form configuration |
Layer overrides. Value keys by layer type: image -> image_url (file), text -> text, empty -> background_color, qr_code -> qr_content, barcode -> barcode_content. |
Collection forms return a bare array of snap objects, not a `data`-wrapped object.
This route has no rate limiting.
Example request
curl
curl -X POST 'https://snapsbrew.com/api/v1/embedded-forms/<formUuid>?signature=<sig>' \
-F 'layers[headline]=Summer sale' \
-F 'layers[logo][email protected]'
Example responses
{
"data": {
"id": "9f1c2d3e",
"media_url": "https://snapsbrew.com/storage/snaps/9f1c2d3e.png",
"type": "image",
"status": "completed",
"is_async": false,
"webhook_url": null,
"completed_at": "2026-05-01T12:00:03Z",
"last_error": null,
"variants": [],
"template_id": "141e8454",
"template_title": "Launch card",
"created_at": "2026-05-01T12:00:00Z"
}
}
{
"message": "Not found."
}
{
"message": "The form does not include any templates."
}