thirds.ai Image Packs API

The Image Packs API from thirds.ai — 4 operation(s) for image packs.

Operations 4

POST /v1/image-packs Create an image pack #
GET /v1/image-packs/{id} Get an image pack's status #
POST /v1/image-packs/{id}/retry Retry an image pack's failed members #
GET /v1/image-packs/archive/{token} Download an image pack's ZIP archive #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/thirds-ai:thirds-ai-image-packs-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

thirds-ai-image-packs-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: thirds.ai Image Packs API
  version: 1.0.0
  description: Turn one design into content at scale. Create branded images and PDFs for your campaigns and clients. Automate each new version through our API or your AI tools. Render saved templates with new data, or send HTML directly. Every error uses one envelope, every response carries an x-request-id header, and every JSON request body rejects fields it does not expect.
servers:
- url: https://thirds.ai
tags:
- name: Image Packs
paths:
  /v1/image-packs:
    post:
      summary: Create an image pack
      description: 'Render one saved template version at every requested size: original for the version''s own canvas, a saved size id, a preset slug, or a WxH custom size adapted from the version''s original. Creates one normal image job per size. A size that cannot be adapted fails immediately with resize_source_unsupported; the other sizes still run. The ledger reserves one credit per job, settles it on success, and releases it on failure.'
      operationId: createImagePack
      security:
      - bearerAuth: []
      parameters:
      - name: Idempotency-Key
        in: header
        required: true
        schema:
          type: string
          minLength: 1
          maxLength: 255
          pattern: ^[ -~]+$
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImagePackCreate'
            examples:
              socialSet:
                value:
                  template_id: tpl_2f6a2f6a2f6a2f6a2f6a2f6a2f6a2f6a
                  version: 3
                  data:
                    headline: Autumn sale
                  format: png
                  sizes:
                  - square-post
                  - story
                  - 1200x628
      responses:
        '201':
          description: The pack was created, or an earlier request with the same idempotency key and body is replayed.
          headers:
            x-request-id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImagePack'
        '400':
          $ref: '#/components/responses/Error'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/AccountSuspended'
        '404':
          $ref: '#/components/responses/Error'
        '409':
          $ref: '#/components/responses/Error'
        '413':
          $ref: '#/components/responses/Error'
        '415':
          $ref: '#/components/responses/Error'
        '429':
          $ref: '#/components/responses/Error'
        '500':
          $ref: '#/components/responses/Error'
        '503':
          $ref: '#/components/responses/Error'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '431':
          $ref: '#/components/responses/RequestHeadersTooLarge'
      tags:
      - Image Packs
  /v1/image-packs/{id}:
    parameters:
    - name: id
      in: path
      required: true
      schema:
        type: string
        pattern: ^pack_[0-9a-f]{32}$
    get:
      summary: Get an image pack's status
      description: Returns the pack with each member's own state and, once any member has succeeded, a signed archive_url for the ZIP of every succeeded file.
      operationId: getImagePack
      security:
      - bearerAuth: []
      responses:
        '200':
          description: The pack's current status.
          headers:
            x-request-id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImagePack'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/AccountSuspended'
        '404':
          $ref: '#/components/responses/Error'
        '500':
          $ref: '#/components/responses/Error'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '431':
          $ref: '#/components/responses/RequestHeadersTooLarge'
      tags:
      - Image Packs
  /v1/image-packs/{id}/retry:
    post:
      summary: Retry an image pack's failed members
      description: Creates one new job for every member whose last attempt failed or that never reached a job. A queued, running, or already succeeded member is left untouched.
      operationId: retryImagePack
      security:
      - bearerAuth: []
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          pattern: ^pack_[0-9a-f]{32}$
      responses:
        '200':
          description: The pack after retry, with a new job for each member that was retried.
          headers:
            x-request-id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImagePackRetry'
        '401':
          $ref: '#/components/responses/Error'
        '403':
          $ref: '#/components/responses/AccountSuspended'
        '404':
          $ref: '#/components/responses/Error'
        '429':
          $ref: '#/components/responses/Error'
        '500':
          $ref: '#/components/responses/Error'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '431':
          $ref: '#/components/responses/RequestHeadersTooLarge'
      tags:
      - Image Packs
  /v1/image-packs/archive/{token}:
    get:
      summary: Download an image pack's ZIP archive
      description: Stream a ZIP of one pack's succeeded members, in requested order with numbered filenames, plus manifest.json recording that order and any failed sizes. The link carries its own authority, so no other credential is read.
      operationId: getImagePackArchive
      parameters:
      - name: token
        in: path
        required: true
        description: The signed archive link.
        schema:
          type: string
      responses:
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '431':
          $ref: '#/components/responses/RequestHeadersTooLarge'
        '200':
          description: The ZIP archive of succeeded members plus manifest.json.
          headers:
            x-request-id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/zip:
              schema:
                type: string
                format: binary
        '403':
          description: The link is genuine but its time is over.
          headers:
            x-request-id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: The link is not valid, or the pack has no succeeded member to archive.
          headers:
            x-request-id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: An internal error occurred.
          headers:
            x-request-id:
              $ref: '#/components/headers/XRequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      tags:
      - Image Packs
components:
  responses:
    MethodNotAllowed:
      description: The method is not allowed on this route.
      headers:
        x-request-id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    AccountSuspended:
      description: The authenticated account is suspended. The code is account_suspended.
      headers:
        x-request-id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    RequestHeadersTooLarge:
      description: The request has more than 64 headers or more than 32 KiB of header names and values.
      headers:
        x-request-id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
    Error:
      description: The one error envelope every backend response uses.
      headers:
        x-request-id:
          $ref: '#/components/headers/XRequestId'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
  schemas:
    ErrorEnvelope:
      type: object
      description: The one error shape every backend response uses.
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
              - account_suspended
              - account_concurrency_limited
              - abuse_limited
              - ai_failure_limit_reached
              - ai_needs_paid_credits
              - already_subscribed
              - auth_unavailable
              - batch_row_limit
              - billing_unavailable
              - brand_asset_account_limit_reached
              - brand_asset_invalid
              - brand_asset_kind_invalid
              - brand_asset_kind_mismatch
              - brand_asset_limit_reached
              - brand_asset_too_large
              - brand_asset_type_unsupported
              - brand_data_conflict
              - brand_font_glyphs_exceeded
              - brand_font_tables_invalid
              - brand_image_animated
              - brand_image_dimensions_invalid
              - brand_image_pixels_exceeded
              - brand_kit_colours_invalid
              - brand_kit_conflict
              - brand_kit_limit
              - brand_kit_name_invalid
              - brand_kit_not_found
              - brand_kit_patch_empty
              - brand_kit_tone_invalid
              - brand_kit_unavailable
              - captcha_rejected
              - checkout_superseded
              - cross_origin_rejected
              - csrf_rejected
              - download_expired
              - email_already_set
              - gallery_template_not_found
              - generated_template_invalid
              - idempotency_conflict
              - image_asset_header_unsupported
              - image_asset_invalid
              - image_asset_limit
              - image_asset_not_found
              - image_asset_reference_invalid
              - image_asset_too_large
              - image_asset_type_unsupported
              - image_asset_unavailable
              - image_url_invalid
              - image_url_unavailable
              - insufficient_credits
              - internal_error
              - invalid_cursor
              - invalid_email
              - invalid_event
              - invalid_link
              - invalid_profile
              - invalid_request
              - invalid_upload
              - job_not_finished
              - key_concurrency_limited
              - key_limit_reached
              - method_not_allowed
              - no_billing_customer
              - not_found
              - operation_conflict
              - operation_limit_exceeded
              - operation_pending
              - overage_limit_reached
              - overage_unavailable
              - overloaded
              - playground_busy
              - playground_request_invalid
              - playground_selection_invalid
              - playground_session_limited
              - playground_unavailable
              - policy_version_stale
              - provider_unavailable
              - rate_limited
              - render_probe_busy
              - render_probe_failed
              - render_probe_not_configured
              - render_probe_required
              - render_probe_timeout
              - request_headers_too_large
              - request_too_large
              - resize_timeout
              - signed_out
              - spend_cap_reached
              - template_build_not_found
              - template_data_collection_limit
              - template_data_depth_limit
              - template_data_invalid
              - template_data_limit
              - template_depth_limit
              - template_draft_not_found
              - template_evaluation_error
              - template_invalid_filter_input
              - template_missing_data
              - template_output_limit
              - template_not_found
              - template_schema_complexity
              - template_schema_draft_unsupported
              - template_schema_invalid
              - template_schema_too_large
              - template_size_canvas_mismatch
              - template_size_data_overrides_too_large
              - template_size_duplicate_id
              - template_size_invalid_dimensions
              - template_size_invalid_id
              - template_size_invalid_name
              - template_sizes_too_large
              - template_sizes_too_many
              - template_source_limit
              - template_syntax_error
              - template_timeout
              - template_version_changed
              - template_work_limit
              - testimonial_busy
              - testimonial_invalid
              - testimonial_rate_limited
              - testimonial_unavailable
              - unauthorized
              - unsupported_media_type
              - webhook_limit_reached
              description: A fixed, machine-readable error code.
            message:
              type: string
              description: A fixed, human-readable message.
            request_id:
              type: string
              format: uuid
              description: The identifier this answer also carries in its x-request-id header.
            details:
              type: array
              description: Present on a validation failure. Schema failures return at most 16 entries with bounded data paths and fixed reasons. Values from the request are never repeated.
              items:
                $ref: '#/components/schemas/FieldDetail'
            retry:
              $ref: '#/components/schemas/RetryInfo'
            plan_limit:
              $ref: '#/components/schemas/PlanLimitInfo'
          required:
          - code
          - message
          - request_id
          additionalProperties: false
      required:
      - error
      additionalProperties: false
    TemplateId:
      type: string
      pattern: ^tpl_[0-9a-f]{32}$
    RetryInfo:
      type: object
      description: How long the caller must wait before it retries.
      properties:
        retry_after_seconds:
          type: integer
          minimum: 1
          maximum: 60
      required:
      - retry_after_seconds
      additionalProperties: false
    ImagePack:
      type: object
      properties:
        id:
          type: string
          pattern: ^pack_[0-9a-f]{32}$
        template_id:
          $ref: '#/components/schemas/TemplateId'
        version:
          type: integer
          minimum: 1
        format:
          type: string
          enum:
          - png
          - jpeg
          - webp
        created_at:
          type: string
          format: date-time
        state:
          type: string
          enum:
          - queued
          - running
          - complete
          - partial
          - failed
        members:
          type: array
          items:
            $ref: '#/components/schemas/ImagePackMember'
        archive_url:
          type:
          - string
          - 'null'
          description: A signed ZIP download link, present once any member has succeeded.
      required:
      - id
      - template_id
      - version
      - format
      - created_at
      - state
      - members
      - archive_url
      additionalProperties: false
    ImagePackRetry:
      $ref: '#/components/schemas/ImagePack'
    ImagePackCreate:
      type: object
      properties:
        template_id:
          $ref: '#/components/schemas/TemplateId'
        version:
          type: integer
          minimum: 1
          description: Omitted to use the template's latest version at creation time.
        data:
          type: object
          description: Template data. Each size's own saved data overrides apply over this data. Omitted to use an empty object.
        format:
          type: string
          enum:
          - png
          - jpeg
          - webp
        sizes:
          type: array
          items:
            type: string
          minItems: 1
          maxItems: 20
          description: '1 to 20 different entries: original for the version''s own canvas, a saved size id, a preset slug, or a WxH custom size.'
      required:
      - template_id
      - format
      - sizes
      additionalProperties: false
    FieldDetail:
      type: object
      description: One request field that failed, its fixed safe reason, and an optional bounded source location. Details never carry template source, customer values, rendered output, or raw evaluator prose.
      properties:
        field:
          type: string
          maxLength: 260
          description: The path to the field, such as "pdf.scale". Schema errors use data followed by a JSON Pointer, such as data/items/0/count. The pointer is cut at 256 UTF-8 bytes. Empty for a problem with the whole document.
        reason:
          type: string
          enum:
          - malformed JSON
          - missing field
          - unknown field
          - wrong type
          - invalid value
          - A required value is missing.
          - Use the expected value type.
          - Declare this variable before using it.
          - Choose an allowed value.
          - Use the required format.
          - Add a value.
          - Use a shorter value.
          - Use a number within the allowed range.
          - Check this value against its data rule.
          description: A fixed, safe reason. It never repeats the value the caller sent.
        line:
          type: integer
          minimum: 1
          maximum: 1000000
          description: The one-based template source line when the evaluator provides one within the published bound.
        column:
          type: integer
          minimum: 1
          maximum: 1000000
          description: The one-based template source column when the evaluator provides one within the published bound.
      required:
      - field
      - reason
      additionalProperties: false
    ImagePackMember:
      type: object
      properties:
        position:
          type: integer
          minimum: 0
        size_id:
          type: string
        name:
          type: string
        width:
          type: integer
          minimum: 1
        height:
          type: integer
          minimum: 1
        state:
          type: string
          enum:
          - queued
          - running
          - succeeded
          - failed
        error:
          type:
          - object
          - 'null'
          properties:
            code:
              type: string
          required:
          - code
          additionalProperties: false
        download_url:
          type:
          - string
          - 'null'
      required:
      - position
      - size_id
      - name
      - width
      - height
      - state
      - error
      - download_url
      additionalProperties: false
    PlanLimitInfo:
      type: object
      description: 'Present when the account''s plan causes the refusal: brand_kit_limit and batch_row_limit. It names the limit and the plan that sets it, so a caller can act without a second request. The message text never names the number.'
      properties:
        plan:
          type: string
          enum:
          - scale
          - growth
          - starter
          - pack
          - free
          description: The account's plan at the time of the refusal.
        limit:
          type: integer
          minimum: 1
          description: 'What that plan allows: brand kits for brand_kit_limit, rows in one run for batch_row_limit.'
      required:
      - plan
      - limit
      additionalProperties: false
  headers:
    XRequestId:
      description: The UUID that identifies this request and matches error.request_id on an error response.
      required: true
      schema:
        type: string
        format: uuid
  securitySchemes:
    sessionCookie:
      type: apiKey
      in: cookie
      name: __Host-thirds_session
      description: A browser session. Browser writes also require the matching x-csrf-token header from GET /v1/me.
    bearerAuth:
      type: http
      scheme: bearer
      description: 'An API key''s secret, sent as "Authorization: Bearer thirds_sk_v1_...".'
x-unmatched-v1-responses:
  description: A request below /v1 that matches no operation receives the shared safe envelope. OpenAPI has no standard path item for an unmatched route, so this extension records the fallback contract without claiming that a catch-all operation exists.
  '404':
    $ref: '#/components/responses/NotFound'
  '431':
    $ref: '#/components/responses/RequestHeadersTooLarge'