Subscribr API

Thumbnails

GET

/team/thumbnails/usage

Required Permission scripts:read thumbnails:read

Get current thumbnail generation quota and usage for your team. Returns up to three quota pools: the free pool (included with every plan), an optional add-on pool (monthly subscription), and an optional pack pool (one-time purchased credits). The total_remaining field provides the combined remaining generations across all pools.

Rate limit: 60 requests per minute

Request

No request body required.

Response (200)

Response Example
{
    "success": true,
    "data": {
        "eligible": true,
        "free_pool": {
            "limit": 5,
            "used": 2,
            "reserved": 1,
            "remaining": 2,
            "next_reset": "2026-04-01"
        },
        "addon_pool": {
            "limit": 50,
            "used": 10,
            "reserved": 0,
            "remaining": 40,
            "next_reset": "2026-04-15"
        },
        "pack_pool": {
            "limit": 100,
            "used": 5,
            "reserved": 0,
            "remaining": 95,
            "next_reset": null
        },
        "total_remaining": 137
    }
}

Response Fields

Field Type Description
success boolean Request success
data.eligible boolean Whether the team is eligible for thumbnail generation (requires active subscription)
data.free_pool object Free pool included with every plan
data.free_pool.limit integer Monthly free generation limit
data.free_pool.used integer Completed generations this period
data.free_pool.reserved integer In-progress generations (counted against remaining until completed or released)
data.free_pool.remaining integer Available generations (limit minus used minus reserved)
data.free_pool.next_reset string|null Pool reset date (Y-m-d format)
data.addon_pool object|null Monthly add-on subscription pool (null if not subscribed). Same fields as free_pool.
data.pack_pool object|null One-time purchased credit pack (null if none purchased). Same fields as free_pool. next_reset is always null — pack credits do not expire.
data.total_remaining integer Combined remaining across all active pools
POST

/channels/{id}/thumbnails/generations

Required Permission scripts:write thumbnails:write

Create an asynchronous thumbnail generation for a channel. Three main modes: (1) **Idea-based** — provide an idea_id to generate a final 2K thumbnail from an existing idea. (2) **Brainstorm** — provide a prompt (no idea_id) to generate concept sketches at 1K resolution. Brainstorm results are stored as concept variations on a new idea; to produce final 2K thumbnails, call this endpoint again with the returned idea_id. (3) **Clone** — provide a clone_strategy and reference_image_url to generate thumbnails that match an existing thumbnail's style. The generation runs in the background; poll the returned run_id for status or use callback_url for async notification.

Rate limit: 12 requests per minute

Request

JSON body. Path id is your Subscribr channel ID. Requires active subscription (403 if ineligible).

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Request Body Fields

Field Type Required Description
idea_id integer No Idea-based or improvement mode. Must belong to channel.
prompt string No Required for brainstorm/clone when idea_id omitted. Max 2000.
topic string No Brainstorm context. Max 1000.
num_variations integer No 1–8. Default 1 with idea_id, 4 without. Each variation reserves one quota unit when idea_id set.
callback_url string No HTTPS callback (not team webhooks). Max 2048.
callback_secret string No Signs callback body via X-Subscribr-Signature. Max 255.
improvement_mode boolean No Requires idea_id, feedback, reference_variation_url.
feedback string No Required when improvement_mode=true. Max 5000.
reference_variation_url string No HTTPS URL. Required when improvement_mode=true.
clone_strategy string No direct_reference or style_analysis
reference_image_url string No HTTPS reference image. Required when clone_strategy set.
Example Request Body
{
    "idea_id": 42,
    "num_variations": 3,
    "callback_url": "https://partner.example.com/subscribr/thumbnail-callback",
    "callback_secret": "whsec_thumbnail_partner_secret"
}

Response (202)

Response Example
{
    "success": true,
    "data": {
        "run_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
        "run_ids": [
            "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d"
        ],
        "status": "queued"
    }
}

Response Fields

Field Type Description
data.run_id string Primary generation run ID (UUID). Use this to poll status via the Get Generation Status endpoint.
data.run_ids array All run IDs for this request. When num_variations > 1 with an idea_id, each variation gets its own run ID that can be polled individually.
data.status string Initial status (always "queued")
data.idea_id integer Returned only for clone modes — the auto-created idea ID
  • Clone with style_analysis: When clone_strategy=style_analysis, the response has a different shape: { idea_id, status: "style_analysis_pending", message }. Style analysis runs asynchronously before thumbnail generation. Use a callback_url to be notified when analysis completes, then call this endpoint again with the returned idea_id to generate the final thumbnail.
  • Quota consumption: Quota is reserved per generation run. When num_variations > 1 with an idea_id, each variation gets its own run_id and consumes one quota unit. Brainstorm mode (no idea_id) reserves one unit for the batch. Reserved quota is released if a run fails.

Error Responses

Status Error code Description
403 not eligible for thumbnail generation No active subscription
404 Idea not found in this channel Invalid idea_id
429 (quota) Insufficient thumbnail quota
GET

/channels/{id}/thumbnails/generations/{runId}

Required Permission scripts:read thumbnails:read

Get the current status and results of a thumbnail generation. When the status is "completed", the output_urls array contains URLs to the generated thumbnail images. Poll this endpoint after creating a generation to track progress.

Rate limit: 120 requests per minute

Request

No request body required.

Parameters

Name Type Description
id integer Channel ID (path parameter).
runId string Generation run ID returned from the Create endpoint (path parameter).

Response (200)

Response Example
{
    "success": true,
    "data": {
        "run_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
        "status": "completed",
        "idea_id": null,
        "output_urls": [
            "https://subscribr.ai/storage/thumbnails/9b1deb4d_v1.png",
            "https://subscribr.ai/storage/thumbnails/9b1deb4d_v2.png"
        ],
        "created_at": "2026-02-27T10:30:00Z",
        "updated_at": "2026-02-27T10:30:45Z"
    }
}

Response Fields

Field Type Description
data.run_id string Generation run identifier (UUID)
data.status string Status: queued (processing), completed (output ready), or failed
data.idea_id integer|null Linked idea ID (present when using idea-based or clone modes)
data.output_urls array Generated thumbnail image URLs (populated when status is "completed", empty otherwise)
data.output_urls[] string URL to a generated thumbnail image
data.created_at string ISO 8601 creation timestamp
data.updated_at string ISO 8601 last update timestamp (indicates when status last changed)
GET

/channels/{id}/thumbnails/generations

Required Permission scripts:read thumbnails:read

List past thumbnail generation runs for a channel. Returns a paginated list (15 per page) ordered by most recent first. Optionally filter by source_type to narrow results to a specific generation mode.

Rate limit: 120 requests per minute

Request

Optional query parameters to filter and paginate results.

Parameters

Name Type Description
id integer Channel ID (path parameter).
source_type string Filter by ThumbnailUsageEvent source_type: api_generate (idea-based and brainstorm API runs), idea_improve, thumbnail_clone
page integer Page number (default 1).

Response (200)

Response Example
{
    "success": true,
    "data": [
        {
            "run_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
            "status": "completed",
            "source_type": "api_generate",
            "idea_id": 42,
            "output_urls": [
                "https://subscribr.ai/storage/thumbnails/9b1deb4d_v1.png"
            ],
            "created_at": "2026-02-27T10:30:00Z"
        }
    ],
    "meta": {
        "current_page": 1,
        "last_page": 3,
        "per_page": 15,
        "total": 42
    }
}

Response Fields

Field Type Description
data[] array List of generation run objects
data[].run_id string Run identifier (UUID) — use with the Get Generation Status endpoint
data[].status string Status: queued, completed, or failed
data[].source_type string api_generate, idea_improve, or thumbnail_clone
data[].idea_id integer|null Linked idea ID (null for brainstorm runs without a pre-existing idea)
data[].output_urls array Generated thumbnail URLs (empty for queued/failed runs)
data[].created_at string ISO 8601 creation timestamp
meta.current_page integer Current page number
meta.last_page integer Total number of pages
meta.per_page integer Items per page (15)
meta.total integer Total matching generation runs
GET

/channels/{id}/thumbnails/board

Required Permission thumbnails:read

Read the channel's Thumbnail Studio board: a spatial canvas of image tiles (imported thumbnails, uploads, AI variations, exports) and editable text overlays. Each channel has one board. Returns every item with its position, status, and image URL. Items with status "generating" are still rendering — poll this endpoint until they turn "ready". The studio_url field links to the board in the Subscribr app.

Rate limit: 120 requests per minute

Request

No request body required.

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Response (200)

Response Example
{
    "success": true,
    "data": {
        "channel_id": 1,
        "board_id": 12,
        "studio_url": "https://subscribr.ai/channels/1/thumbnails",
        "credits_remaining": 42,
        "items": [
            {
                "id": 311,
                "type": "image",
                "status": "ready",
                "x": 48,
                "y": 128,
                "width": 320,
                "height": 180,
                "frame_id": 310,
                "url": "https://subscribr.ai/storage/thumbnails/boards/311.png",
                "label": "How I fixed my retention",
                "source": "youtube_video"
            }
        ]
    }
}

Response Fields

Field Type Description
data.board_id integer|null Board ID (null until the first write command creates the board)
data.studio_url string Link to the board in Thumbnail Studio
data.credits_remaining integer Combined remaining thumbnail credits across all pools
data.items[] array Board items ordered by z-index
data.items[].type string image, text, shape, or frame
data.items[].status string ready, generating, or failed
data.items[].url string Image URL (image items only, once ready)
data.items[].content string Headline text (text items only)
data.items[].usage string Reference tag: creator_face, style, product, background, or screenshot
data.items[].assigned_script_id integer|null Set when this image is the current thumbnail of a script (project)
data.items[].assigned_script_title string|null Title of the script this image is assigned to
POST

/channels/{id}/thumbnails/board/images

Required Permission thumbnails:write

Import reference images onto the board as a labeled frame. Sources my_recent, my_top_viewed, and my_top_outlier pull the channel's own YouTube thumbnails; source urls adds up to 12 external image URLs, optionally tagged with a usage such as creator_face (exact likeness) or style (visual style to copy). Added images can then be passed as reference_item_ids to Create Board Generation.

Rate limit: 12 requests per minute

Request

JSON body. Boards hold at most 500 images; requests past the cap return 422.

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Request Body Fields

Field Type Required Description
source string Yes my_recent, my_top_viewed, my_top_outlier, or urls.
urls array No Required when source is urls. Up to 12 image URLs.
usage string No Tag for URL imports: creator_face, style, product, background, or screenshot.
label string No Frame label. Max 80. Default "API imports".

Response (200)

Response Example
{
    "success": true,
    "data": {
        "board_id": 12,
        "items": [
            {
                "id": 311,
                "type": "image",
                "status": "ready",
                "x": 48,
                "y": 128,
                "width": 320,
                "height": 180,
                "frame_id": 310,
                "url": "https://example.com/reference.png",
                "usage": "style",
                "source": "upload"
            }
        ]
    }
}

Response Fields

Field Type Description
data.items[] array The new frame plus one image item per imported thumbnail
data.items[].id integer Item ID — use as a reference_item_id when generating
POST

/channels/{id}/thumbnails/board/generations

Required Permission thumbnails:write

Render new thumbnail variations onto the board from a prompt plus selected reference items. Spends 1 thumbnail credit per variation. Rendering is asynchronous (typically 10-60 seconds per image): the response returns placeholder items with status "generating" — poll Get Thumbnail Board until they turn "ready". Failed renders release their credit automatically. Text is kept out of the generated image by default; words in the prompt become an editable text overlay instead. Set allow_text to true to bake text into the image.

Rate limit: 12 requests per minute

Request

JSON body. Requires an active subscription (403 if ineligible) and available thumbnail credits (429 when exhausted).

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Request Body Fields

Field Type Required Description
prompt string Yes What to generate. 3-2000 characters.
reference_item_ids array No Up to 6 ready image item IDs to use as visual references.
variations integer No 1-8. Default 2. Each variation spends one credit.
allow_text boolean No Bake text into the image. Default false (text becomes an editable overlay).

Response (200)

Response Example
{
    "success": true,
    "data": {
        "board_id": 12,
        "credits_spent": 2,
        "credits_remaining": 40,
        "items": [
            {
                "id": 312,
                "type": "image",
                "status": "generating",
                "x": 48,
                "y": 360,
                "width": 320,
                "height": 180,
                "prompt": "Shocked face pointing at a giant chart",
                "source": "generation"
            }
        ],
        "note": "Rendering is asynchronous (typically 10-60 seconds per image). Poll GET /thumbnails/board until these items turn \"ready\"."
    }
}

Response Fields

Field Type Description
data.credits_spent integer Credits reserved for this request
data.items[] array Placeholder image items (plus an editable text overlay when the prompt asked for words and allow_text is false)
data.items[].status string "generating" until the render completes
POST

/channels/{id}/thumbnails/board/edits

Required Permission thumbnails:write

Change one ready board image with a plain-language instruction such as "remove the text" or "make the sky stormy". Spends 1 thumbnail credit. Non-destructive: the edit arrives as a new item beside the original, which is never altered, so you can compare takes and keep the one you want. Pass an optional region to confine the change to a rectangle of the image — pixels outside it are guaranteed identical to the original, because Subscribr composites the model output back over the source rather than trusting the model to stay inside the lines. Rendering is asynchronous (typically 10-60 seconds): poll Get Thumbnail Board until the new item turns "ready". A failed edit releases its credit automatically.

Rate limit: 12 requests per minute

Request

JSON body. Requires an active subscription (403 if ineligible) and an available thumbnail credit (429 when exhausted).

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Request Body Fields

Field Type Required Description
item_id integer Yes A ready image item on this board to edit.
instruction string Yes One change to make. 3-2000 characters.
region object No Confine the edit to a rectangle: x, y, width, height as fractions of the image (0-1). Regions under 2% in either dimension are ignored.

Response (200)

Response Example
{
    "success": true,
    "data": {
        "board_id": 12,
        "credits_spent": 1,
        "credits_remaining": 39,
        "items": [
            {
                "id": 318,
                "type": "image",
                "status": "generating",
                "x": 392,
                "y": 360,
                "width": 320,
                "height": 180,
                "prompt": "Remove the text",
                "source": "generation"
            }
        ],
        "note": "The edit renders asynchronously as a new item beside the original, which is left unchanged. Poll GET /thumbnails/board until it turns \"ready\"."
    }
}

Response Fields

Field Type Description
data.credits_spent integer Always 1 for an edit
data.items[] array The new placeholder item for the edit; the source item is untouched
data.items[].status string "generating" until the edit completes
POST

/channels/{id}/thumbnails/board/text

Required Permission thumbnails:write

Add or update an editable headline overlay. Overlay text stays out of the generated image on purpose so it can be edited and swapped freely. Place a new overlay over an image with over_item_id, or pass item_id to update an existing overlay. Styling defaults come from the channel's analyzed thumbnail identity. Use Export Board Image to flatten overlays into a final PNG.

Rate limit: 12 requests per minute

Request

JSON body. content is required when creating a new overlay.

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Request Body Fields

Field Type Required Description
content string No Headline text. Max 200. Required without item_id.
item_id integer No Existing text item to update.
over_item_id integer No Image item to place a new overlay over.
x integer No Board X position.
y integer No Board Y position.
font string No impact, anton, bebas, archivo, montserrat, oswald, bangers, luckiest, poppins, or system.
size integer No Font size, 16-240.
fill string No Text color as #RRGGBB.
stroke string No Outline color as #RRGGBB.
stroke_width integer No Outline width, 0-40.
background string No Highlight box color as #RRGGBB, or null for none.
align string No left, center, or right.

Response (200)

Response Example
{
    "success": true,
    "data": {
        "board_id": 12,
        "item": {
            "id": 313,
            "type": "text",
            "status": "ready",
            "x": 62,
            "y": 140,
            "width": 292,
            "height": 60,
            "content": "I WAS WRONG",
            "source": "agent"
        }
    }
}

Response Fields

Field Type Description
data.item object The text overlay item
POST

/channels/{id}/thumbnails/board/export

Required Permission thumbnails:write

Flatten one ready image with every text overlay that overlaps it into a final 1280x720 PNG. Returns the stored URL and adds the export back onto the board as a new item. This is how an agent produces the finished, downloadable thumbnail.

Rate limit: 12 requests per minute

Request

JSON body.

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Request Body Fields

Field Type Required Description
item_id integer Yes A ready image item on the board.

Response (200)

Response Example
{
    "success": true,
    "data": {
        "board_id": 12,
        "url": "https://subscribr.ai/storage/thumbnails/boards/export-314.png",
        "item": {
            "id": 314,
            "type": "image",
            "status": "ready",
            "x": 408,
            "y": 128,
            "width": 320,
            "height": 180,
            "url": "https://subscribr.ai/storage/thumbnails/boards/export-314.png",
            "source": "export"
        },
        "overlays_flattened": 1
    }
}

Response Fields

Field Type Description
data.url string URL of the flattened 1280x720 PNG
data.overlays_flattened integer Number of text overlays baked into the export
POST

/channels/{id}/thumbnails/board/assign-to-script

Required Permission thumbnails:write

Make a ready board image the thumbnail of a project (script) on this channel. Uses the same exclusive winner semantics as selecting a thumbnail on the Kanban board: the image is stored as a script attachment, marked as the thumbnail winner, and shown on the project card and detail view. The board item is stamped with assigned_script_id and assigned_script_title so later board reads show which image belongs to which project.

Rate limit: 12 requests per minute

Request

JSON body. The script must belong to the channel.

Parameters

Name Type Description
id integer Subscribr channel ID (path).

Request Body Fields

Field Type Required Description
item_id integer Yes A ready image item on the board.
script_id integer Yes The script (project) to receive the thumbnail.

Response (200)

Response Example
{
    "success": true,
    "data": {
        "script_id": 88,
        "attachment_id": 402,
        "thumbnail_url": "https://subscribr.ai/storage/kanban-attachments/402.png"
    }
}

Response Fields

Field Type Description
data.attachment_id integer The script attachment holding the stored copy
data.thumbnail_url string URL of the assigned thumbnail