openapi: 3.0.3
info:
  version: 1.0.0
  title: API Reference - Abyssale
  license:
    name: Proprietary
    url: https://www.abyssale.com/terms-of-service
  x-logo:
    url: https://cdn.prod.website-files.com/6214efb2d4b5d94158f2ff03/674734715bd8e93b78fd7042_abyssale_v3_black.svg
    altText: Abyssale logo
    href: https://www.abyssale.com
    backgroundColor: '#FAFAFA'
  description: |
    ### Abyssale API Reference

    Abyssale is a **programmatic creative asset generation API** for creating marketing visuals,
    ad creatives, videos, and print-ready PDFs at scale. Design once in Abyssale, then generate
    thousands of personalized variations — across every format, channel, and language —
    via a single REST API call.

    This documentation is about the Abyssale `Rest API`. If you would like to discover other Abyssale features or to have a comprehensive understanding on how everything works, go to the [Abyssale developers hub](https://developers.abyssale.com).

    Base URL: `https://api.abyssale.com`

    #### General Rest API information:
    - Data exchange format: **JSON**. All API calls must contain the `Content-Type: application/json` header.
    - Rate limits: **10 requests/second**
    - Only **successful generated assets are counted** in your API usage.
    - Trial plan: **30 requests are included**.
    - Available Integrations: [Zapier](https://zapier.com/apps/abyssale/integrations), [Make (ex Integromat)](https://www.make.com/en/integrations/abyssale), [Airtable](https://airtable.com/marketplace/blkB14c3EShbFLlh4/abyssale) & [n8n](https://n8n.io/integrations/abyssale/) _(if you prefer using nocode)_

    #### Which approach should I use?

    | Use case | Recommended approach |
    |----------|----------------------|
    | **Personalized images in emails** (rendered on open) | Static design → [Dynamic image URL](#tag/Dynamic-Images) |
    | **Embed a live, customizable image on a website** | Static design → [Dynamic image URL](#tag/Dynamic-Images) |
    | **Single image on demand** (synchronous response) | [Synchronous generation](#tag/Asset-Generation/operation/generateAsset) |
    | **Bulk campaign creatives** across multiple formats | [Async generation](#tag/Asset-Generation/operation/generateMultiFormatMedia) |
    | **Animated GIF or video** for social/ads | Animated design → [Async generation](#tag/Asset-Generation/operation/generateMultiFormatMedia) with `gif` or `video` options |
    | **HTML5 banner ads** for ad networks | Animated design → [Async generation](#tag/Asset-Generation/operation/generateMultiFormatMedia) with `html5` options |
    | **Print-ready PDF** (single page) | Printer design → [Async generation](#tag/Asset-Generation/operation/generateMultiFormatMedia) with `print` options |
    | **Multi-page print document** (brochure, catalog) | Printer multipage design → [Multi-page PDF](#tag/Asset-Generation/operation/generateMultiPagePdf) |

    # Authentication

    Abyssale uses **API Key Authentication**.
    Your API key is passed along with every API call, allowing Abyssale to identify your company account and access your data.

    [How to get your API Key?](https://developers.abyssale.com/rest-api/authentication#how-to-get-an-api-key) 

    <SecurityDefinitions />

    #### Common error responses (applicable to all endpoints):
    - `401 Unauthorized` — missing or invalid API key
    - `429 Too Many Requests` — rate limit exceeded (10 req/s) or insufficient credits
    - `500 Internal Server Error` — unexpected server-side failure
servers:
  - url: https://api.abyssale.com
    description: Main Production Server
tags:
  - name: Designs
    description: |
      A design is a layout including at least:
      - one format (dimension, i.e. Facebook feed 1200x628 or IAB 300x250)
      - one element (text, button, image, shape...)

      All elements have their own properties that can be customized (color, text payload, image...).

      Once designed, all properties of the design will act as a reference for subsequent image generation. Obviously, those properties can be overridden by sending new parameters in the generation API call.

      Abyssale provides a list of free template designs in the Template Library page. Feel free to use one to start designing your design instead of doing it from scratch.

      **All of your designs are listed in the different project pages, only those are accessible via API.**
  - name: Asset Generation
    description: |
      Generate images, animated videos, GIFs, HTML5 banners, and print-ready PDFs
      programmatically from your Abyssale designs.

      The generation workflow is simple:
      1. Build your design in Abyssale (or pick one from the Template Library)
      2. Send your dynamic data — text, images, colors — via the API
      3. Receive the generated asset URL in the response

      Use the **synchronous** endpoint for single-image generation with an immediate response.
      Use the **asynchronous** endpoint for bulk banner creation across multiple formats at once —
      ideal for marketing automation, personalized ad campaigns, and batch asset production at scale.
  - name: Fonts
    description: |
      Retrieve the fonts available in your Abyssale workspace. Fonts can be applied
      to text and button elements during image generation. Two types are supported:
      Google Fonts (free, always available) and custom fonts uploaded to your workspace.

      Reference a font by its ID when overriding the `font` property in a generation request.
  - name: Exports
    description: |
      Export a collection of previously generated banners as a single ZIP archive.
      Useful for downloading bulk assets for offline use, sharing with creative teams,
      or archiving a campaign's outputs. The export is processed asynchronously —
      provide a callback URL to receive a webhook notification when the archive is ready.
  - name: Files
    description: |
      Retrieve metadata and download URLs for generated files (images, videos, GIFs,
      HTML5 banners, and PDFs). Listen to webhook events to be notified in real time
      when a file or batch generation completes.
  - name: Projects
    description: |
      Projects let you organize your designs into logical groups — for example by
      campaign, client, or content type. All designs must belong to a project to
      be accessible via the API. Use projects to scope design retrieval and keep
      large design libraries manageable.
  - name: Workspace Templates
    description: |
      Workspace templates are master designs shared across your organization. Duplicate
      them into any project to create editable copies — useful for spinning up campaign
      variants, onboarding new clients, or maintaining brand-consistent starting points.
      The duplication is processed asynchronously; poll the status endpoint to track progress.
  - name: Dynamic Images
    description: |
      Dynamic images are live image URLs that render on-the-fly based on query parameters.
      Once created for a design, the URL can be embedded anywhere — emails, websites,
      social posts — and customized with different text, colors, or images per use case,
      without additional API calls. Ideal for personalization at scale.
paths:
  /designs:
    get:
      operationId: listDesigns
      summary: List all designs
      description: |
        Retrieve all designs available in your Abyssale workspace. Each design defines
        the visual layout, available formats (dimensions), and configurable elements
        (text, images, shapes, etc.) that can be overridden during image generation.
        Filter by design type or project category using query parameters.
      tags:
        - Designs
      parameters:
        - in: query
          name: project_id
          schema:
            type: string
            format: uuid
          required: false
          description: Unique identifier (UUID) of a project. Filter designs by project.
        - in: query
          name: type
          schema:
            type: string
            enum:
              - static
              - animated
              - printer
              - printer_multipage
          required: false
          description: Filter designs by one of these types static, animated, printer, printer_multipage
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                type: array
                items:
                  allOf:
                    - $ref: '#/components/schemas/Design'
                    - type: object
                      properties:
                        preview_url:
                          type: string
                          format: uri
                          example: https://production-banners.s3-eu-west-1.amazonaws.com/templates/e0d292f2-ec21-11e9-a539-3c408bf94155/a9b3c668-7b84-4924-adf0-815dae727d32.png
                          description: Preview Image URL of the first design format
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - api_key: []
  /designs/{designId}:
    get:
      operationId: getDesign
      summary: Get design details
      description: |
        Retrieve the full specification of a design: its formats (dimensions and preview URLs),
        all configurable elements with their properties, and any template variables defined
        in text layers. Use this endpoint to discover what data to send in a generation request.
      tags:
        - Designs
      parameters:
        - in: path
          name: designId
          schema:
            type: string
            format: uuid
          required: true
          description: Unique identifier (UUID) of the design
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Design'
                  - type: object
                    properties:
                      formats:
                        type: array
                        description: |
                          The list of formats available in the design.

                          The id property can be used to specify the format you would like to generate in the generation API call.
                        items:
                          $ref: '#/components/schemas/DesignFormat'
                      elements:
                        type: array
                        description: |
                          The list of all elements (& customizable properties) contained in the design.

                          `name` is the layer name (root is a special element that allows to customize the image background color.)

                          `attributes` contains the list of all customizable properties:
                          - `id`: The attribute ID
                          - `values`: the related value for this attribute in each format (if defined)
                        items:
                          $ref: '#/components/schemas/DesignElement'
                      variables:
                        type: object
                        description: |
                          Variables used within the text layers of the design.
                          Keys represent variable names (without braces), and values
                          represent the placeholder format in the design (e.g. "{name}").
                        additionalProperties:
                          type: string
                        example:
                          name: '{name}'
                          title: '{title}'
        '404':
          description: Design Not found
      security:
        - api_key: []
  /designs/{designId}/formats/{formatSpecifier}:
    get:
      tags:
        - Designs
      operationId: getDesignFormat
      summary: Get format details
      description: |
        Retrieve detailed information for a specific format within a design, including
        dimensions, unit, preview URL, dynamic image URL, element layout, and variables.
        Useful for inspecting a single format before generating or building dynamic image URLs.
      parameters:
        - name: designId
          in: path
          required: true
          schema:
            type: string
          description: Unique identifier of the design
        - name: formatSpecifier
          in: path
          required: true
          schema:
            type: string
          description: Format name or UID
      responses:
        '200':
          description: Format details retrieved successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: new-format
                    description: Format identifier
                  uid:
                    type: string
                    format: uuid
                    example: 6248b96f-581a-43f0-9863-85e1b7d0ec05
                    description: Unique ID for the format instance
                  width:
                    type: integer
                    example: 3333
                    description: Width of the format in specified units
                  height:
                    type: integer
                    example: 666
                    description: Height of the format in specified units
                  unit:
                    type: string
                    example: px
                    description: Unit of measurement for dimensions
                  preview_url:
                    type: string
                    format: uri
                    example: https://production-banners.s3-eu-west-1.amazonaws.com/templates/e0d292f2-ec21-11e9-a539-3c408bf94152/21aff1a9-bcde-4294-8320-be6cae651381.png
                    description: URL to preview image of this format
                  dynamic_image_url:
                    type: string
                    format: uri
                    example: https://img.abyssale.com/673f0cb6-f1f6-4f7d-8ea2-4a0ed317efbe/6248b96f-581a-43f0-9863-85e1b7d0ec0a
                    description: URL to the dynamically generated image
                  design:
                    $ref: '#/components/schemas/Design'
                  elements:
                    type: array
                    description: List of all elements (& customizable properties) contained in the design format
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          example: root
                          description: Element name
                        type:
                          type: string
                          example: container
                          description: Element type
                        settings:
                          type: object
                          properties:
                            is_mandatory:
                              type: boolean
                              example: false
                              description: Whether the element is mandatory
                        attributes:
                          type: array
                          items:
                            type: object
                            properties:
                              id:
                                type: string
                                example: background_color
                                description: Attribute identifier
                              help:
                                type: string
                                example: '6 or 8 digits hexadecimal background color (i.e. #F3F3F3) of the banner'
                                description: Help text for the attribute
                              value:
                                type: string
                                example: '#FFFFFF'
                                description: Value of the attribute for this format
                        layout:
                          type: object
                          properties:
                            x:
                              type: integer
                              example: 0
                            'y':
                              type: integer
                              example: 0
                            width:
                              type: integer
                              example: 3333
                            height:
                              type: integer
                              example: 666
                  variables:
                    type: object
                    description: |
                      Variables used within the text layers of the design format (if any).
                      Keys represent variable names (without braces), and values
                      represent the placeholder format in the design (e.g. "{name}").
                    additionalProperties:
                      type: string
                    example:
                      name: '{name}'
                      title: '{title}'
        '404':
          description: Format Not found
      security:
        - api_key: []
  /designs/{designId}/dynamic-image-url:
    post:
      tags:
        - Dynamic Images
      operationId: createDynamicImageUrl
      summary: Create a dynamic image URL
      description: Creates a dynamic image URL for a given design. Only one dynamic image is allowed per design. Subsequent calls return the existing dynamic image. Use `enable_rate_limit` in the request body to enable API rate limiting for this image & `enable_production_mode` to enable production mode (default is test mode).
      parameters:
        - name: designId
          in: path
          required: true
          schema:
            type: string
          description: Unique identifier of the design
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                enable_rate_limit:
                  type: boolean
                  default: false
                  description: Enable API rate limiting for this dynamic image
                enable_production_mode:
                  type: boolean
                  default: false
                  description: Enable Production mode for this dynamic image
            example:
              enable_rate_limit: true
              enable_production_mode: true
      responses:
        '200':
          description: Existing dynamic image retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicImageResponse'
        '201':
          description: Dynamic image successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DynamicImageResponse'
        '404':
          description: Design Not found
      security:
        - api_key: []
  /banners/{bannerId}:
    get:
      operationId: getFile
      summary: Get generated file
      description: |
        Retrieve the metadata and download URLs for a previously generated file
        (image, video, GIF, HTML5 banner, or PDF). Returns both the S3 storage URL
        and a CDN-hosted URL suitable for embedding directly in websites or emails.
      tags:
        - Files
      parameters:
        - in: path
          name: bannerId
          schema:
            type: string
            format: uuid
          required: true
          description: Unique identifier (UUID) of the file
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Banner'
        '404':
          description: A banner with the specified ID was not found.
      security:
        - api_key: []
  /banner-builder/{designId}/generate:
    post:
      tags:
        - Asset Generation
      operationId: generateImage
      summary: Generate an image (synchronous)
      description: |
        Synchronously generate a single image from a design. Send your dynamic data
        (text, images, colors) as element overrides in the request body and receive
        the generated file URL immediately in the response.

        Best for: real-time image generation, single-asset workflows, or when you need
        the result inline without polling.

        For bulk generation across multiple formats, use the asynchronous endpoint instead.
      parameters:
        - in: path
          name: designId
          schema:
            type: string
            format: uuid
          required: true
          description: Unique identifier (UUID) of the design
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                elements:
                  $ref: '#/components/schemas/Elements'
                template_format_name:
                  type: string
                  example: facebook-post
                  description: Corresponds to the format ID you would like to generate (only mandatory when your design contains several formats).
                image_file_type:
                  type: string
                  enum:
                    - png
                    - jpeg
                    - webp
                    - avif
                    - pdf
                    - auto
                  description: Output file type. Defaults to the design's configured type when omitted.
                file_compression_level:
                  type: integer
                  example: 80
                  description: Percentage of compression applied.
                  minimum: 1
                  maximum: 100
              required:
                - elements
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Banner'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          description: |
            Rate limit exceeded (10 req/s) **or** plan/credit restriction.
            Inspect the `message` field to distinguish the two causes — see the
            [`TooManyRequests`](#/components/responses/TooManyRequests) and
            [`PaymentRequired`](#/components/responses/PaymentRequired) components
            for the full list of possible messages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                rate_limit:
                  summary: Request rate limit exceeded
                  value:
                    message: 429 Too Many Requests
                not_enough_credits:
                  summary: Insufficient generation credits
                  value:
                    message: 429 Not enough credits, please update your plan
                format_not_in_plan:
                  summary: Output format not included in plan
                  value:
                    message: 429 GIF is not included in your plan, please update your plan.
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - api_key: []
  /async/banner-builder/{designId}/generate:
    post:
      tags:
        - Asset Generation
      summary: Generate images/videos/PDFs asynchronously (multi-format)
      operationId: generateMultiFormatMedia
      description: |
        Asynchronously generate multiple formats of an image, video, GIF, HTML5 banner,
        or PDF in a single API call. Ideal for bulk banner production, multi-channel
        marketing campaigns, and programmatic ad creative generation at scale.

        Specify one or more format IDs to generate, or omit the list to generate all
        formats defined in the design. Provide a `callback_url` to receive a webhook
        notification when generation is complete, or poll
        `GET /generation-request/{generationRequestId}` for status.

        You can find available formats and elements by calling `GET /designs/{designId}`.
      parameters:
        - in: path
          name: designId
          schema:
            type: string
            format: uuid
          required: true
          description: Unique identifier (UUID) of the design
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                elements:
                  $ref: '#/components/schemas/Elements'
                template_format_names:
                  type: array
                  items:
                    type: string
                  example:
                    - facebook-feed
                    - instagram-post
                    - iab-medium
                  description: |
                    **Format IDs you would like to generate**.

                    _The array can be empty or not provided if you want to generate all formats of this design._
                callback_url:
                  type: string
                  format: uri
                  description: |
                    **The url that will be called once generation of your images is done.**

                    We will do a `POST` request of the [NewBannerBatch](#operation/newBannerBatch) event on this URL with a JSON payload.
                image_file_type:
                  type: string
                  enum:
                    - png
                    - jpeg
                    - webp
                    - avif
                    - gif
                    - pdf
                    - html5
                    - mp4
                    - webm
                    - auto
                  description: Output file type. Depends on the design type (static/animated/printer). Defaults to the design's configured type when omitted.
                file_compression_level:
                  type: integer
                  minimum: 1
                  maximum: 100
                  description: Percentage of compression applied.
                html5:
                  type: object
                  description: HTML5 output options (animated designs only)
                  properties:
                    page_title:
                      type: string
                      maxLength: 255
                      default: Abyssale page title example
                    click_tag:
                      type: string
                      maxLength: 255
                      default: https://www.abyssale.com
                    ad_network:
                      type: string
                      maxLength: 255
                      default: default
                      description: Ad network identifier (e.g. "default", "doubleclick", "sizmek")
                    include_backup_image:
                      type: boolean
                      nullable: true
                    repeat:
                      type: integer
                      minimum: -1
                      maximum: 100
                      nullable: true
                      description: Number of loop repetitions. -1 = infinite.
                gif:
                  type: object
                  description: GIF output options (animated designs only)
                  properties:
                    max_fps:
                      type: integer
                      minimum: 2
                      maximum: 9
                    repeat:
                      type: integer
                      minimum: -1
                      maximum: 100
                      description: Number of loop repetitions. -1 = infinite.
                video:
                  type: object
                  description: Video output options (animated designs only)
                  properties:
                    fps:
                      type: integer
                      minimum: 2
                      maximum: 30
                print:
                  type: object
                  description: Print output options (printer/printer_multipage designs only)
                  properties:
                    color_profile:
                      type: string
                      format: uuid
                      description: UUID of the color profile to apply
                    display_crop_marks:
                      type: boolean
                original_visual_id:
                  type: string
                  format: uuid
                  description: UUID of the original visual this generation is based on.
              required:
                - elements
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                type: object
                properties:
                  generation_request_id:
                    type: string
                    format: uuid
                    description: Unique identifier (UUID) of the batch generation
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          description: |
            Rate limit exceeded (10 req/s) **or** plan/credit restriction.
            Inspect the `message` field to distinguish the two causes — see the
            [`TooManyRequests`](#/components/responses/TooManyRequests) and
            [`PaymentRequired`](#/components/responses/PaymentRequired) components
            for the full list of possible messages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                rate_limit:
                  summary: Request rate limit exceeded
                  value:
                    message: 429 Too Many Requests
                not_enough_credits:
                  summary: Insufficient generation credits
                  value:
                    message: 429 Not enough credits, please update your plan
                format_not_in_plan:
                  summary: Output format not included in plan
                  value:
                    message: 429 GIF is not included in your plan, please update your plan.
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - api_key: []
  /fonts:
    get:
      tags:
        - Fonts
      operationId: listFonts
      summary: List available fonts
      description: |
        Retrieve all fonts available in your Abyssale workspace, including Google Fonts
        and any custom fonts you have uploaded. Use a font's `id` to override the font
        on text or button elements in a generation request.
      parameters:
        - in: query
          name: type
          required: false
          schema:
            type: string
            enum:
              - google
              - custom
          description: Filter fonts by type. Omit to return both Google and custom fonts.
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Font'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - api_key: []
  /async/banners/export:
    post:
      tags:
        - Exports
      operationId: exportBanners
      summary: Export banners as ZIP archive (asynchronous)
      description: |
        Asynchronously package a set of previously generated banners into a single ZIP
        archive for download. Provide a `callback_url` to receive a webhook notification
        when the export is ready, containing the archive URL.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                ids:
                  type: array
                  description: An array of string that corresponds to the banners IDs you would like to export.
                  items:
                    type: string
                    format: uuid
                    example: 64238d01-d402-474b-8c2d-fbc957e9d290
                callback_url:
                  type: string
                  format: uri
                  description: The url that will be called once the generation of your export is done.
                  example: https://your-webhook.com/export-abyssale
              required:
                - ids
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                type: object
                properties:
                  export_id:
                    type: string
                    example: 64238d01-d402-474b-8c2d-fbc957e9d290
                    description: Unique identifier (UUID) of the asynchronous export. Keep it to be able to identify the asynchronous response.
                required:
                  - export_id
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
      security:
        - api_key: []
  /async/banner-builder/{designId}/generate-multipage-pdf:
    post:
      tags:
        - Asset Generation
      operationId: generateMultiPagePdf
      summary: Generate a multi-page PDF (asynchronous)
      description: |
        Asynchronously generate a multi-page print-ready PDF from a printer_multipage design.
        Each page is defined by a `pages` dictionary entry, allowing different element
        overrides per page — ideal for brochures, catalogs, and variable data printing.

        Provide a `callback_url` to receive a webhook when the PDF is ready,
        or poll `GET /generation-request/{generationRequestId}` for status.

        You can find available formats and elements by calling `GET /designs/{designId}`.
      parameters:
        - in: path
          name: designId
          schema:
            type: string
            format: uuid
          required: true
          description: Unique identifier (UUID) of the design
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                pages:
                  $ref: '#/components/schemas/Pages'
                callback_url:
                  type: string
                  format: uri
                  description: |
                    **The url that will be called once generation of your PDF is done.**

                    We will do a `POST` request of the [NewBannerBatch](#operation/newBannerBatch) event on this URL with a JSON payload.
                print:
                  type: object
                  description: Print output options
                  properties:
                    color_profile:
                      type: string
                      format: uuid
                      description: UUID of the color profile to apply
                    display_crop_marks:
                      type: boolean
                original_visual_id:
                  type: string
                  format: uuid
                  description: UUID of the original visual this generation is based on.
              required:
                - pages
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                type: object
                properties:
                  generation_request_id:
                    type: string
                    format: uuid
                    description: Unique identifier (UUID) of the batch generation
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          description: |
            Rate limit exceeded (10 req/s) **or** plan/credit restriction.
            Inspect the `message` field to distinguish the two causes — see the
            [`TooManyRequests`](#/components/responses/TooManyRequests) and
            [`PaymentRequired`](#/components/responses/PaymentRequired) components
            for the full list of possible messages.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              examples:
                rate_limit:
                  summary: Request rate limit exceeded
                  value:
                    message: 429 Too Many Requests
                not_enough_credits:
                  summary: Insufficient generation credits
                  value:
                    message: 429 Not enough credits, please update your plan
                format_not_in_plan:
                  summary: Output format not included in plan
                  value:
                    message: 429 GIF is not included in your plan, please update your plan.
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - api_key: []
  /generation-request/{generationRequestId}:
    get:
      operationId: getGenerationRequest
      summary: Poll async generation request status
      description: |
        Poll the status of an asynchronous generation request. Use this endpoint to track
        the progress of a batch generation operation started with the async generate endpoint.
        The result is available for 7 days after generation.
      tags:
        - Asset Generation
      parameters:
        - in: path
          name: generationRequestId
          required: true
          schema:
            type: string
            format: uuid
          description: Unique identifier (UUID) of the generation request
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerationRequestStatus'
        '202':
          description: Generation still in progress
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GenerationRequestStatus'
        '404':
          description: Generation request not found
      security:
        - api_key: []
  /projects:
    get:
      operationId: listProjects
      summary: List projects
      description: |
        Retrieve all projects in your workspace. Projects group designs into logical
        collections. Only designs that belong to a project are accessible via the API.
      tags:
        - Projects
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ProjectSummary'
              examples:
                projects_list:
                  summary: List of projects
                  value:
                    - id: 9d00e9fe-9bd5-4471-acad-baa702a867e9
                      name: Animation Tests
                      created_at_ts: 1654763057
                    - id: bdf9ab44-f5fd-47ad-881d-a45906901233
                      name: HTML5 Tests
                      created_at_ts: 1663767647
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - api_key: []
    post:
      operationId: createProject
      summary: Create a project
      description: |
        Create a new project to organize your designs. Assign designs to this project
        in the Abyssale editor to make them accessible via the API.
      tags:
        - Projects
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 2
                  maxLength: 100
                  description: Name of the project
                  example: Summer Campaign 2024
              required:
                - name
      responses:
        '200':
          description: Project created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectSummary'
              examples:
                created_project:
                  summary: Successfully created project
                  value:
                    id: cb2c4add-4867-11f0-96f2-0a00d9eb8f78
                    name: Summer Campaign 2024
                    created_at_ts: 1749827107
        '400':
          $ref: '#/components/responses/BadRequest'
      security:
        - api_key: []
  /workspace-templates/{companyTemplateId}/use:
    post:
      operationId: duplicateWorkspaceTemplate
      summary: Duplicate a workspace template into a project
      description: |
        Copy a shared workspace template into one of your projects, creating an editable
        design instance. The duplication is asynchronous — use the returned
        `duplication_request_id` to poll for completion via
        `GET /design-duplication-requests/{duplicateRequestId}`.
      tags:
        - Workspace Templates
      parameters:
        - in: path
          name: companyTemplateId
          schema:
            type: string
            format: uuid
          required: true
          description: Unique identifier (UUID) of the workspace template to duplicate
          example: 0c967bd0-4137-4690-ad70-249aa021c68b
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                project_id:
                  type: string
                  format: uuid
                  description: Target project ID where the template will be duplicated
                  example: d59adee9-4867-11f0-96f2-0a00d9eb8f78
                name:
                  type: string
                  description: Optional custom name for the duplicated template
                  example: My Custom Template
                  maxLength: 100
                  minLength: 2
              required:
                - project_id
            examples:
              basic_duplication:
                summary: Basic template duplication
                value:
                  project_id: d59adee9-4867-11f0-96f2-0a00d9eb8f78
              custom_name_duplication:
                summary: Duplication with custom name
                value:
                  project_id: d59adee9-4867-11f0-96f2-0a00d9eb8f78
                  name: Holiday Campaign Template
      responses:
        '200':
          description: Duplication request accepted and processing
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DuplicationRequest'
              examples:
                duplication_started:
                  summary: Duplication request created
                  value:
                    duplication_request_id: 40c32a4e-4869-11f0-96f2-0a00d9eb8f78
        '404':
          description: Workspace template Or Project not found
      security:
        - api_key: []
  /design-duplication-requests/{duplicateRequestId}:
    get:
      operationId: getDuplicationRequest
      summary: Poll template duplication request status
      description: |
        Poll the status of a template duplication request. Use this endpoint to track
        the progress of an asynchronous duplication operation.
      tags:
        - Workspace Templates
      parameters:
        - in: path
          name: duplicateRequestId
          schema:
            type: string
            format: uuid
          required: true
          description: Unique identifier (UUID) of the duplication request
          example: 40c32a4e-4869-11f0-96f2-0a00d9eb8f78
      responses:
        '200':
          description: Duplication request status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DuplicationRequestStatus'
              examples:
                completed_duplication:
                  summary: Successfully completed duplication
                  value:
                    request_id: 40c32a4e-4869-11f0-96f2-0a00d9eb8f78
                    status: COMPLETED
                    created_at_ts: 1749827734
                    completed_at_ts: 1749827736
                    errored_at_ts: null
                    target_project:
                      id: d59adee9-4867-11f0-96f2-0a00d9eb8f78
                      name: HTML5 Tests
                      created_at_ts: 1749827125
                    designs:
                      - original_design_id: 0c967bd0-4137-4690-ad70-249aa021c68b
                        target_design_id: afb1a61a-6c50-4bc3-a49b-3381822d4e81
                        target_design_name: New Design name
                pending_duplication:
                  summary: Duplication in progress
                  value:
                    request_id: 40c32a4e-4869-11f0-96f2-0a00d9eb8f78
                    status: IN_PROGRESS
                    created_at_ts: 1749827734
                    completed_at_ts: null
                    errored_at_ts: null
                    target_project:
                      id: d59adee9-4867-11f0-96f2-0a00d9eb8f78
                      name: HTML5 Tests
                      created_at_ts: 1749827125
                    designs: []
                failed_duplication:
                  summary: Failed duplication
                  value:
                    request_id: 40c32a4e-4869-11f0-96f2-0a00d9eb8f78
                    status: ERROR
                    created_at_ts: 1749827734
                    completed_at_ts: null
                    errored_at_ts: 1749827750
                    target_project:
                      id: d59adee9-4867-11f0-96f2-0a00d9eb8f78
                      name: HTML5 Tests
                      created_at_ts: 1749827125
                    designs: []
        '404':
          description: Duplication request not found
      security:
        - api_key: []
x-webhooks:
  newBanner:
    post:
      security: []
      summary: File generated
      description: A new file (image, video, GIF, HTML5 banner, or PDF) has been generated and is ready to download.
      operationId: newImage
      tags:
        - Files
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Banner'
      responses:
        '200':
          description: Return a 200 status to indicate that the data was received successfully
  newBannerBatch:
    post:
      security: []
      summary: Batch generation completed
      description: |
        An asynchronous batch generation request has completed. Contains the full list
        of generated files and any per-format errors. Triggered by
        `POST /async/banner-builder/{designId}/generate`.
      operationId: newBannerBatch
      tags:
        - Files
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  format: uuid
                  description: Unique identifier (UUID) of the batch generation
                banners:
                  type: array
                  items:
                    $ref: '#/components/schemas/Banner'
                  description: List of generated images
                errors:
                  type: array
                  items:
                    type: object
                    properties:
                      template_format_name:
                        type: string
                        description: The image related to this format name cannot be generated
                      reason:
                        type: string
                        description: The error reason
                  description: If any errors occur, they will be listed under that property
              required:
                - id
                - banners
      responses:
        '200':
          description: Return a 200 status to indicate that the data was received successfully
  newExport:
    post:
      security: []
      summary: Banner export archive ready
      description: |
        An asynchronous banner export has completed. The ZIP archive containing all
        requested banners is available at the provided `archive_url`.
      operationId: newExport
      tags:
        - Exports
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                export_id:
                  type: string
                  format: uuid
                  example: 38cb7df3-1160-4824-8531-2bacde2b6517
                  description: ID of the export
                archive_url:
                  type: string
                  format: uri
                  example: https://production-banners.s3.eu-west-1.amazonaws.com/demo/export_38cb7df3-1160-4824-8531-2bacde2b6517.zip
                  description: The zip public URL
                requested_at:
                  type: number
                  example: 1642150000
                  description: Timestamp at which the export has been requested
                generated_at:
                  type: number
                  example: 1642150002
                  description: Timestamp at which the export has been done
      responses:
        '200':
          description: Return a 200 status to indicate that the data was received successfully
components:
  responses:
    BadRequest:
      description: Bad Request — the request body or parameters are invalid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            invalid_json:
              summary: Malformed request body
              value:
                message: Invalid JSON
            validation_error:
              summary: Field-level validation failure
              value:
                message: Invalid parameters
                errors:
                  - field: elements.root.background_color
                    message: 'Must be a 6 or 8 hexadecimal color (given: #zzz)'
    Unauthorized:
      description: Unauthorized — missing or invalid API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            missing_or_invalid_key:
              summary: Missing or invalid API key
              value:
                message: 'Unauthorized: missing or invalid API key.'
                id: unauthorized
            plan_no_api_access:
              summary: Subscription plan does not include API access
              value:
                message: '401 Unauthorized: Your subscription plan does not include API access.'
                id: api_access_denied
    NotFound:
      description: Not Found — the requested resource does not exist.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            resource_not_found:
              summary: Design not found
              value:
                message: 404 Template UUID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' not found
                id: template_not_found
            endpoint_not_found:
              summary: Endpoint does not exist
              value:
                message: The endpoint 'GET /unknown/path' does not exist.
                id: endpoint_not_found
    TooManyRequests:
      description: Too Many Requests — request rate limit exceeded (10 req/s).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            message: 429 Too Many Requests
            id: rate_limit_exceeded
    PaymentRequired:
      description: |
        Plan or credit restriction — the account does not have sufficient credits or the
        requested output format is not included in the current plan.

        > **Note:** The API returns these errors as HTTP `429` rather than `402`. Distinguish
        > them from rate-limit errors by inspecting the `message` field.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            not_enough_credits:
              summary: Insufficient generation credits
              value:
                message: 429 Not enough credits, please update your plan
            not_enough_ai_credits:
              summary: Insufficient AI credits
              value:
                message: 429 Not enough AI credits, either buy additional AI credits or update your plan
            html5_not_in_plan:
              summary: HTML5 output not included in plan
              value:
                message: 429 HTML5 is not included in your plan, please update your plan.
            mp4_not_in_plan:
              summary: MP4 output not included in plan
              value:
                message: 429 MP4 is not included in your plan, please update your plan.
            gif_not_in_plan:
              summary: GIF output not included in plan
              value:
                message: 429 GIF is not included in your plan, please update your plan.
            print_pdf_not_in_plan:
              summary: Printable PDF not included in plan
              value:
                message: 429 Printable PDF is not included in your plan, please update your plan.
            web_pdf_not_in_plan:
              summary: Web PDF not included in plan
              value:
                message: 429 Web PDF is not included in your plan, please update your plan.
    InternalServerError:
      description: Internal Server Error — an unexpected error occurred on our side.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            message: Internal server error
            id: internal_server_error
  securitySchemes:
    api_key:
      description: All of your Abyssale requests must contain a `x-api-key header` with your API Key.
      type: apiKey
      name: x-api-key
      in: header
  schemas:
    ErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: Human-readable error message.
        id:
          type: string
          description: |
            Machine-readable error code identifier. Present on most errors.

            Common values: `template_not_found`, `template_not_static`, `format_not_found`,
            `cannot_build_banner`, `rate_limit_exceeded`, `unauthorized`, `api_access_denied`,
            `endpoint_not_found`, `body_validation_errors`, `internal_server_error`.
        errors:
          type: array
          description: |
            Field-level validation errors, present on 400 responses when `message` is
            `"Invalid parameters"`. Each entry identifies the failing field and the reason.
          items:
            type: object
            properties:
              field:
                type: string
                description: Dot-notation path to the invalid field (e.g. `elements.root.background_color`).
              message:
                type: string
                description: Human-readable reason the field failed validation.
            required:
              - field
              - message
      required:
        - message
    Banner:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 64238d01-d402-474b-8c2d-fbc957e9d290
        version:
          type: integer
          example: 1
          description: Version number of the generated file.
        sharing_id:
          type: string
          format: uuid
          example: 5fcec999-2bfb-4dd7-ba38-2d9e16c49149
          description: Identifier used for sharing this generated file.
        file:
          $ref: '#/components/schemas/File'
        format:
          $ref: '#/components/schemas/Format'
        template:
          $ref: '#/components/schemas/Design'
      required:
        - id
        - file
    File:
      type: object
      properties:
        type:
          type: string
          example: jpeg
          enum:
            - jpeg
            - png
            - pdf
            - gif
            - mp4
            - webm
            - zip
          description: File type
        url:
          type: string
          example: https://production-banners.s3.eu-west-1.amazonaws.com/demo/996739f4-b563-428a-a6e8-ec3cb8bd03d4.jpeg
          description: URL of the banner (useful to download the image).
        cdn_url:
          type: string
          example: https://cdn.abyssale.com/demo/996739f4-b563-428a-a6e8-ec3cb8bd03d4.jpeg
          description: The CDN URL of the banner (useful to host the image; on a website for instance). (A bandwidth usage limit applies, related to your plan). (Not available for zip)
        filename:
          type: string
          example: 996739f4-b563-428a-a6e8-ec3cb8bd03d4.jpeg
          description: Name of the file. If the related design contains a custom naming scheme, the custom name will be available from this property.
      required:
        - type
        - url
    Format:
      type: object
      properties:
        id:
          type: string
          example: facebook-post
          description: Identifier/name of the format.
        width:
          type: integer
          example: 1200
          description: Width of the format.
        height:
          type: integer
          example: 1200
          description: Height of the format.
      required:
        - id
        - width
        - height
    Design:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 64238d01-d402-474b-8c2d-fbc957e9d290
          description: Unique identifier (UUID) of the design.
        name:
          type: string
          example: Ad campaign fall 2025
          description: Name of the design.
        type:
          type: string
          enum:
            - static
            - animated
            - printer
            - printer_multipage
          example: static
          description: Type of the design
        created_at:
          type: integer
          example: 1649942114
          description: Timestamp of when the design has been created.
        updated_at:
          type: integer
          example: 1649942114
          description: Timestamp of when the design has been updated for the last time.
        category_name:
          type: string
          nullable: true
          example: Fall campaigns
          description: Design Category
      required:
        - id
        - name
        - type
        - created_at
        - updated_at
    DesignFormat:
      type: object
      properties:
        id:
          type: string
          example: facebook-post
          description: Unique identifier (name) of the format.
        uid:
          type: string
          format: uuid
          example: 9b57d65e-eb2c-4a74-a51e-4482917c248a
          description: Unique UUID of the format
        width:
          type: number
          example: 1200
          description: Width of the format
        height:
          type: number
          example: 1200
          description: Height of the format
        unit:
          type: string
          example: px
          description: Unit of measurement for dimensions
        preview_url:
          type: string
          format: uri
          example: https://production-banners.s3-eu-west-1.amazonaws.com/templates/e0d292f2-ec21-11e9-a539-3c408bf94155/a9b3c668-7b84-4924-adf0-815dae727d32.png
          description: Preview Image URL of the format
        dynamic_image_url:
          type: string
          format: uri
          example: https://img.abyssale.com/ecf1fe8c-5392-48c2-b6d2-665183a18fe5/9b57d65e-eb2c-4a74-a51e-4482917c248a
          description: URL of the existing dynamic image for this format.
      required:
        - id
        - uid
        - width
        - height
    DesignElement:
      type: object
      properties:
        name:
          type: string
          example: element-name
          description: Layer name (`root` is a special element that allows to customize the image background color.)
        type:
          type: string
          enum:
            - container
            - text
            - button
            - image
            - logo
            - shape
            - illustration
            - rating
            - qrcode
            - chart
            - video
            - audio
          example: text
          description: Layer type
        attributes:
          type: array
          description: List of all attributes
          items:
            type: object
            properties:
              id:
                type: string
                example: payload
                description: The attribute name
              help:
                type: string
                example: Text content (i.e. Lorem ipsum)
                description: An helper to understand what is this attribute
              values:
                type: object
                example:
                  facebook-post: My image title
                additionalProperties:
                  type: string
                  description: The value of the attribute related to a format.
                  x-additionalPropertiesName: format-id
            required:
              - id
              - help
              - values
      required:
        - name
        - type
        - attributes
    Font:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 61568e7c-33c5-11ea-9877-92672c1b8195
          description: Font unique ID, this parameter can be used to force a specific font on a text or a button element.
        name:
          type: string
          example: Ubuntu Mono
          description: The font name
        available_weights:
          type: array
          items:
            oneOf:
              - type: number
                enum:
                  - 100
                  - 200
                  - 300
                  - 400
                  - 500
                  - 600
                  - 700
                  - 800
                  - 900
              - type: string
                enum:
                  - 100-italic
                  - 200-italic
                  - 300-italic
                  - 400-italic
                  - 500-italic
                  - 600-italic
                  - 700-italic
                  - 800-italic
                  - 900-italic
            description: The list of weights supported by this font
        type:
          type: string
          enum:
            - google
            - custom
          description: Either `google` for the Google fonts or `custom` for your uploaded fonts.
      required:
        - id
        - name
        - available_weights
        - type
    RootElement:
      type: object
      properties:
        background_color:
          $ref: '#/components/schemas/backgroundColor'
    Element:
      type: object
      properties:
        hidden:
          type: boolean
          description: '`true`, `false`. If true it hides the current element'
        shadow_color:
          type: string
          description: 6-8 digits hexadecimal color
        shadow_blur:
          type: number
          minimum: 0
          description: Blur in pixels
        shadow_offset_x:
          type: number
          description: Horizontal offset in pixels (can be negative)
        shadow_offset_y:
          type: number
          description: Vertical offset in pixels (can be negative)
      oneOf:
        - $ref: '#/components/schemas/TextElement'
        - $ref: '#/components/schemas/ImageElement'
        - $ref: '#/components/schemas/ButtonElement'
        - $ref: '#/components/schemas/LogoElement'
        - $ref: '#/components/schemas/ShapeElement'
        - $ref: '#/components/schemas/RatingElement'
        - $ref: '#/components/schemas/IllustrationElement'
        - $ref: '#/components/schemas/QRCodeElement'
        - $ref: '#/components/schemas/VideoElement'
        - $ref: '#/components/schemas/AudioElement'
    TextElement:
      type: object
      properties:
        payload:
          $ref: '#/components/schemas/payload'
        color:
          $ref: '#/components/schemas/color'
        background_color:
          $ref: '#/components/schemas/backgroundColor'
        background_padding:
          $ref: '#/components/schemas/backgroundPadding'
        font_size:
          $ref: '#/components/schemas/fontSize'
        font:
          $ref: '#/components/schemas/font'
        font_weight:
          $ref: '#/components/schemas/fontWeight'
        line_height:
          $ref: '#/components/schemas/lineHeight'
        skew_y:
          $ref: '#/components/schemas/skewY'
        alignment:
          $ref: '#/components/schemas/textAlignment'
        stroke_width:
          $ref: '#/components/schemas/strokeWidth'
        stroke_color:
          $ref: '#/components/schemas/strokeColor'
        text_transform:
          $ref: '#/components/schemas/textTransform'
        auto_resize:
          type: boolean
          description: Automatically adjusts the text size to fit within its container. When true, `min_font_size` must also be defined.
        min_font_size:
          type: number
          minimum: 1
          description: Minimum font size allowed when `auto_resize` is enabled.
        max_lines:
          type: number
          minimum: 1
          description: Maximum number of lines allowed.
        text_harmony:
          type: boolean
          description: Attempts to balance line lengths with a maximum variance of 20% between lines. Adjusts character spacing (±20), then reduces font size (up to -10px) if needed.
        text_truncation:
          type: boolean
          description: If the text does not fit, it is truncated and an ellipsis (...) is appended.
        side_border:
          type: string
          enum:
            - left
            - right
            - top
            - bottom
            - none
          description: Defines the side on which a border is rendered. Use `none` to disable an existing side border.
        side_border_thickness:
          type: number
          minimum: 0
          description: Thickness of the side border in pixels.
        side_border_color:
          type: string
          description: Color of the side border. 6-8 digits hexadecimal or cmyka (for print).
        side_border_rounded:
          type: boolean
          description: Whether the border corners are rounded (true) or square (false). Default is false.
        side_border_padding:
          type: number
          minimum: 0
          description: Distance in pixels between the text content and the side border. Default is 0.
        side_border_offset:
          type: number
          description: Moves the border along the perpendicular axis. Positive and negative values shift in opposite directions. Default is 0.
        side_border_spread:
          type: number
          description: Extends the length of the border beyond the text bounding box by the specified number of pixels. Default is 0.
        vars:
          type: object
          additionalProperties:
            type: string
          description: |
            Key-value pairs used to replace variables within the text payload.
            Variables are defined in the design as `{variableName}` placeholders.
            Pass the variable name (without braces) as the key and the replacement value as the value.
          example:
            username: Alice
            title: Spring Sale
    ButtonElement:
      type: object
      properties:
        payload:
          $ref: '#/components/schemas/payload'
        color:
          $ref: '#/components/schemas/color'
        background_color:
          $ref: '#/components/schemas/backgroundColor'
        background_padding:
          $ref: '#/components/schemas/backgroundPadding'
        font_size:
          $ref: '#/components/schemas/fontSize'
        font:
          $ref: '#/components/schemas/font'
        font_weight:
          $ref: '#/components/schemas/fontWeight'
        line_height:
          $ref: '#/components/schemas/lineHeight'
        text_transform:
          $ref: '#/components/schemas/textTransform'
    ImageElement:
      type: object
      properties:
        image_url:
          $ref: '#/components/schemas/imageUrl'
        image_encoded:
          $ref: '#/components/schemas/imageEncoded'
        opacity:
          $ref: '#/components/schemas/opacity'
        fitting_type:
          $ref: '#/components/schemas/fittingType'
        alignment:
          $ref: '#/components/schemas/alignment'
        mask_name:
          $ref: '#/components/schemas/maskName'
        mask_properties:
          $ref: '#/components/schemas/maskProperties'
        filter_name:
          $ref: '#/components/schemas/filterName'
        filter_properties:
          $ref: '#/components/schemas/filterProperties'
        overlay_direction:
          $ref: '#/components/schemas/overlayDirection'
        overlay_color_1:
          $ref: '#/components/schemas/overlayColor1'
        overlay_color_2:
          $ref: '#/components/schemas/overlayColor2'
        remove_bg:
          type: boolean
          description: Activates AI background removal when set to true.
        remove_bg_properties:
          type: object
          description: Additional settings for background removal.
          properties:
            remove_bg_crop:
              type: boolean
              description: Trims the edges of the image after background removal. Default is false.
        auto_focus:
          type: boolean
          description: Activates AI-powered auto-focus to detect and focus on specified objects or people within the image.
        auto_focus_properties:
          type: object
          description: Additional settings for auto-focus.
          properties:
            model:
              type: string
              enum:
                - generic
                - people
                - face
              description: Model used for focusing. `generic` for objects, `people` for human subjects, `face` for face detection. Default is `generic`.
            focus_objects:
              type: array
              items:
                type: string
              description: List of object labels to focus on (generic model only). Uses Open Images Dataset labels.
            focus_framing:
              type: string
              enum:
                - face
                - head
                - shoulders
                - full_body
              description: Specific to `people` model. Defines which part of the subject to frame.
            focus_zoom:
              type: string
              enum:
                - 'off'
                - low
                - medium
                - max
              description: Specific to `people` model. Controls the zoom level applied. Default is `max`.
            focus_target:
              type: string
              enum:
                - largest
                - left
                - middle
                - right
                - all
              description: Specific to `people` model. When multiple subjects are detected, defines which one to target. Default is `all`.
        text_to_image:
          type: string
          description: |
            AI-generated image from a text prompt. Only available for asynchronous generation.
            If `image_url` (except default image) or `image_encoded` is provided, this property is ignored.
          example: A sleek, modern glass villa situated in the middle of a minimalist lavender field.
    LogoElement:
      type: object
      properties:
        image_url:
          $ref: '#/components/schemas/imageUrl'
        image_encoded:
          $ref: '#/components/schemas/imageEncoded'
        alignment:
          $ref: '#/components/schemas/alignment'
    ShapeElement:
      type: object
      properties:
        background_color:
          $ref: '#/components/schemas/backgroundColor'
        pattern_name:
          $ref: '#/components/schemas/patternName'
        pattern_color:
          $ref: '#/components/schemas/patternColor'
        stroke_width:
          $ref: '#/components/schemas/strokeWidth'
        stroke_color:
          $ref: '#/components/schemas/strokeColor'
    RatingElement:
      type: object
      properties:
        rating_score:
          $ref: '#/components/schemas/ratingScore'
        star_dimension:
          $ref: '#/components/schemas/starDimension'
        star_margin:
          $ref: '#/components/schemas/starMargin'
        star_color:
          $ref: '#/components/schemas/starColor'
        background_color:
          $ref: '#/components/schemas/ratingBackgroundColor'
    IllustrationElement:
      type: object
      properties:
        illustration_type:
          $ref: '#/components/schemas/illustrationType'
        illustration_file:
          $ref: '#/components/schemas/illustrationFile'
        illustration_properties:
          $ref: '#/components/schemas/illustrationProperties'
        alignment:
          $ref: '#/components/schemas/alignment'
        opacity:
          $ref: '#/components/schemas/opacity'
    QRCodeElement:
      type: object
      properties:
        background_color:
          $ref: '#/components/schemas/qrcodeBackgroundColor'
        foreground_color:
          $ref: '#/components/schemas/qrcodeForegroundColor'
        payload:
          $ref: '#/components/schemas/qrcodePayload'
        image_url:
          $ref: '#/components/schemas/qrcodeImageUrl'
        hide_icon:
          $ref: '#/components/schemas/qrcodeHideIcon'
    VideoElement:
      type: object
      description: This element is only available for animated design
      properties:
        video_url:
          $ref: '#/components/schemas/videoUrl'
    AudioElement:
      type: object
      description: Audio layer element. Only available for animated designs with MP4 output.
      properties:
        audio_url:
          type: string
          format: uri
          description: |
            **HTTP(s) URL of the audio file.**

            It must be a publicly accessible link with a filesize of 30 MB maximum.

            Supported files: mp3, wav
        max_volume:
          type: number
          minimum: 0
          maximum: 1
          description: Volume level. 1 = default volume, 0.5 = half volume, 0 = silent. Default is 1.
          example: 1
        speed:
          type: number
          minimum: 0.25
          maximum: 2
          description: Playback speed. 1 = 100%, 0.5 = 50%. Default is 1.
          example: 1
    Elements:
      type: object
      description: A `dictionary` containing all elements with properties you would like to override form the default design (keys correspond to layer names)
      additionalProperties:
        x-additionalPropertiesName: element-name
        oneOf:
          - $ref: '#/components/schemas/RootElement'
          - $ref: '#/components/schemas/Element'
          - $ref: '#/components/schemas/VideoElement'
          - $ref: '#/components/schemas/AudioElement'
    Pages:
      type: object
      description: A `dictionary` containing all pages with properties you would like to override form the default design (keys correspond to layer names)
      additionalProperties:
        type: object
        x-additionalPropertiesName: page_
        properties:
          root:
            $ref: '#/components/schemas/RootElement'
        required:
          - root
    DuplicationRequest:
      type: object
      properties:
        duplication_request_id:
          type: string
          format: uuid
          example: 40c32a4e-4869-11f0-96f2-0a00d9eb8f78
          description: Unique identifier for tracking the duplication process
      required:
        - duplication_request_id
    DuplicationRequestStatus:
      type: object
      properties:
        request_id:
          type: string
          format: uuid
          example: 40c32a4e-4869-11f0-96f2-0a00d9eb8f78
          description: Unique identifier of the duplication request
        status:
          type: string
          enum:
            - INIT
            - IN_PROGRESS
            - ERROR
            - COMPLETED
          example: COMPLETED
          description: Current status of the duplication request
        created_at_ts:
          type: integer
          example: 1749827734
          description: Unix timestamp when the duplication request was created
        completed_at_ts:
          type: integer
          nullable: true
          example: 1749827736
          description: Unix timestamp when the duplication was completed (null if not completed)
        errored_at_ts:
          type: integer
          nullable: true
          example: null
          description: Unix timestamp when the duplication failed (null if not failed)
        target_project:
          $ref: '#/components/schemas/ProjectSummary'
        designs:
          type: array
          items:
            $ref: '#/components/schemas/DuplicatedDesign'
          description: List of duplicated designs (empty if not completed)
      required:
        - request_id
        - status
        - created_at_ts
        - target_project
        - designs
    ProjectSummary:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: d59adee9-4867-11f0-96f2-0a00d9eb8f78
          description: Unique identifier of the project
        name:
          type: string
          example: HTML5 Tests
          description: Name of the project
        created_at_ts:
          type: integer
          example: 1749827125
          description: Unix timestamp when the project was created
      required:
        - id
        - name
        - created_at_ts
    DuplicatedDesign:
      type: object
      properties:
        original_design_id:
          type: string
          format: uuid
          example: 0c967bd0-4137-4690-ad70-249aa021c68b
          description: ID of the original workspace template
        target_design_id:
          type: string
          format: uuid
          example: afb1a61a-6c50-4bc3-a49b-3381822d4e81
          description: ID of the newly created template in your project
        target_design_name:
          type: string
          example: Design Name
          description: Name of the duplicated template
      required:
        - original_design_id
        - target_design_id
        - target_design_name
    GenerationRequestStatus:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier of the generation request
        is_finalized:
          type: boolean
          description: Whether the generation is complete. `false` when the request returns 202, `true` when it returns 200.
        banners:
          type: array
          items:
            $ref: '#/components/schemas/Banner'
          description: List of generated files (populated once finalized)
        errors:
          type: array
          items:
            type: object
            properties:
              template_format_name:
                type: string
                description: The format name that failed to generate
              reason:
                type: string
                description: The error reason
          description: Per-format errors, if any occurred during generation
      required:
        - id
        - is_finalized
        - banners
    DynamicImageResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique ID of the dynamic image
        design_id:
          type: string
          format: uuid
          description: Design ID associated with this dynamic image
        formats:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
                description: Format name
              uid:
                type: string
                description: Format unique identifier (UUID)
              width:
                type: integer
                description: Width of the format in pixels
              unit:
                type: string
                description: Unit of measurement for dimensions, e.g. px
              height:
                type: integer
                description: Height of the format in pixels
              dynamic_image_url:
                type: string
                format: uri
                description: URL to the dynamically generated image for this format
            required:
              - id
              - uid
              - width
              - unit
              - height
              - dynamic_image_url
          description: List of formats available for this dynamic image
      required:
        - id
        - design_id
        - formats
      example:
        id: a12b3c4d-5e6f-7890-abcd-ef1234567890
        design_id: b2c3d4e5-f6a7-8901-bcde-f12345678901
        formats:
          - id: one-format
            uid: 11111111-2222-3333-4444-555555555555
            width: 3333
            unit: px
            height: 666
            dynamic_image_url: https://img.abyssale.com/a12b3c4d-5e6f-7890-abcd-ef1234567890/one-format
          - id: another-format
            uid: 66666666-7777-8888-9999-000000000000
            width: 1920
            unit: px
            height: 1080
            dynamic_image_url: https://img.abyssale.com/a12b3c4d-5e6f-7890-abcd-ef1234567890/another-format
    backgroundColor:
      type: string
      description: |
        **The background color displayed behind the element.**

        3 filling modes are available:
        - `Monochrome`: 6 or 8 hexadecimal colors starting with a **#**. _i.e. #EAEAEA or #FF00FF55_
        - `Linear Gradient`: `linear-gradient(x1% y1% x2% y2%,offset1% #color1 opacity1,offset2% #color2 opacity2)` _i.e. linear-gradient(0% 0% 100% 0%,0% #1a47ff 1,100% #b65151 1)_
        - `Cmyka` (print only): `cmyka(c,m,y,k)` or `cmyka(c,m,y,k,alpha)` where each value is 0–100. _i.e. cmyka(0,100,100,0,100)_
      example: '#FF0000'
    payload:
      type: string
      description: |
        **The text content**. *Example: Lorem Ipsum*

        - [How can I force specific line breaks?](https://developers.abyssale.com/image-generation-properties.html#color)
        - [How can I add decorations to specific parts of a text?](https://developers.abyssale.com/image-generation-properties.html#color)
      minLength: 1
      maxLength: 2048
    color:
      type: string
      description: |
        **The text color.**

        3 filling modes are available:
        - `Monochrome`: 6 or 8 hexadecimal colors starting with a **#**. _i.e. #EAEAEA or #FF00FF55_
        - `Linear Gradient`: `linear-gradient(x1% y1% x2% y2%,offset1% #color1 opacity1,offset2% #color2 opacity2)`
        - `Cmyka` (print only): `cmyka(c,m,y,k)` or `cmyka(c,m,y,k,alpha)` where each value is 0–100.
    backgroundPadding:
      type: string
      description: |
        **The padding of the background color around the text.** *Example: 10*

        _This parameter will only be used if a background color is defined._

        - String: Two numbers separated by a space: First number represents the vertical padding in pixels & the second the vertical padding. For instance: 0 10 : 0 as vertical padding & 10 as horizontal
        - Number: Paddings (Horizontal & vertical) in pixels. _i.e. 10_
    fontSize:
      type: number
      minimum: 1
      description: '**Font size in pixels** *Example: 20*'
    font:
      type: string
      format: uuid
      description: |
        **Force a specific font by ID**. *Example: 6156907e-33c5-11ea-9877-92672c1b8195*

        The fonts list is available by calling the [GET /fonts](#tag/Fonts) API route.
    fontWeight:
      type: number
      enum:
        - 100
        - 200
        - 300
        - 400
        - 500
        - 600
        - 700
        - 800
        - 900
      description: |
        **Force a font weight**. *Example: 500*

        | Value | Corresponding name |
        |-----|-----|
        | 100   | Thin   |
        | 200   | Extra Light   |
        | 300   | Light   |
        | 400   | Regular   |
        | 500   | Medium   |
        | 600   | Semi Bold   |
        | 700   | Bold   |
        | 800   | Extra Bold   |
        | 900   | Black   |

        _If the font does not contain the given font weight, the nearest weight will be used._
    lineHeight:
      type: number
      minimum: 1
      description: |
        **Force line height in percentage** *Example: 130*

        __This parameter is only applied when the text is a multiline one.__
    skewY:
      type: number
      minimum: -20
      maximum: 20
      description: '**Slant text on the y axis** *Example: 20*'
    textAlignment:
      type: string
      enum:
        - top
        - middle
        - bottom
        - left
        - center
        - right
        - top left
        - top center
        - top right
        - middle left
        - middle center
        - middle right
        - bottom left
        - bottom right
        - bottom center
      description: |
        **The text alignment.** *Example: left*

        __If given, the text position will be computed from the text bounding box defined within the design.__
    textTransform:
      type: string
      description: |
        **Text transformation style.** Force the text to be transformed to one of the following options: - `uppercase`: All letters become uppercase (e.g., `EXAMPLE`) - `lowercase`: All letters become lowercase (e.g., `example`) - `titlecase`: The first letter of each word is capitalized (e.g., `Example Text`) - `capitalize`: Only the first letter of the entire text is capitalized (e.g., `Example text`)
      enum:
        - uppercase
        - lowercase
        - titlecase
        - capitalize
    strokeWidth:
      type: number
      minimum: 0
      maximum: 40
      description: '**Width of the stroke** *Example: 10*'
    strokeColor:
      type: string
      description: |
        **Stroke Color. 6-8 digits Hexa color.**. *Example: #FF0000*

        __If your design does not contain any stroke, this color won't be visible__
    imageUrl:
      type: string
      format: uri
      description: |
        **HTTP(s) URL of the image** *Example: https://www.abyssale.com/imge/abyssale_logo.png*

        __It must be a public accessible link and have a filesize of 10 mo maximum.__

        Supported files: jpeg, png, webp, svg, gif
    imageEncoded:
      type: string
      description: |
        **Base64 encoded image as value.** *Example: /9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQE...*

        __If the image_url is given, this parameter will not be used.__
    opacity:
      type: number
      minimum: 0
      maximum: 100
      description: '**Opacity of the image** *Example: 60*'
    fittingType:
      type: string
      enum:
        - cover
        - fill
      description: |
        **Defines the way the image will be inserted in the bounding box**

        Two properties are supported:

        - `cover`: It will force the image to fill entirely the area without changing the aspect ratio (hence the image will be cropped if its ratio is not the same as the container)
        - `fill`: The image will be displayed entirely within the box.
    alignment:
      type: string
      enum:
        - top
        - middle
        - bottom
        - left
        - center
        - right
        - top left
        - top center
        - top right
        - middle left
        - middle center
        - middle right
        - bottom left
        - bottom right
        - bottom center
      description: '**The image alignment.** *Example: left*'
    maskName:
      type: string
      enum:
        - circle
        - rounded_corners
        - blob
        - squircle
        - pentagon
        - hexagon
        - parallelogram
      description: |
        **A mask can be added to the image**.

        5 masks are available:
        - `circle`: The image will be rendered as a circle. No additional property is available.
        - `rounded_corners`: Corners of the image will be rounded. It requires another property: `mask_properties`.
        - `blob`: The image will be rendered as a blob. No additional property is available.
        - `squircle`: The image will be rendered as a squircle. No additional property is available.
        - `pentagon`: The image will be rendered as a pentagon. No additional property is available.
        - `hexagon`: The image will be rendered as a hexagon. No additional property is available.
        - `parallelogram`: The image will be rendered as a parallelogram. No additional property is available.
    maskProperties:
      type: object
      properties:
        radius:
          oneOf:
            - type: number
            - type: object
      description: |
        **When the rounded_corners mask is applied, this parameter allows to define the radius**.

        Two types of radius is supported:
        - A number, that allows to define all corners' radius at once. *Example: {"radius": 20}*
        - An object, that allows to customize each corner's radius individually.
          4 properties are available: (`tl` = top left, `tr` = top right, `br` = bottom right, `bl` = bottom left)

        *Example: {"radius": {
          "tl": 0,
          "tr": 56,
          "br": 56,
          "bl": 20
        }}*
    filterName:
      type: string
      enum:
        - grayscale
        - duotone
      description: |
        **A filter can be added to the image.** *Example: grayscale*

        2 filters are available:
        - `grayscale`: It converts the input image to grayscale. No additional property is available.
        - `duotone`: Apply a duotone filter to the image. It requires another property: `filter_properties`
    filterProperties:
      type: object
      properties:
        name:
          type: string
          enum:
            - blue_orange
            - deep_green_light_green
            - BrightRed_light_yellow
            - brown_pale_green
            - brown_beige
            - deep_blue_green
            - deep_blue_red
            - deep_purple_orange
            - deep_purple_beige
            - deep_purple_pale_green
            - deep_blue_pale_green
      description: |
        **When the duotone mask is applied, this parameter allows to define the duotone filter to apply**.
        *Example: { "name": "blue_orange" }*
    patternName:
      type: string
      enum:
        - bubbles
        - cage
        - cross
        - doubleCircle
        - drops
        - parkay
        - pills
        - plus
        - star
        - ticTac
        - ticTacFilled
        - triangle
        - wiggle
      description: |
        **A pattern can be added to the shape**.

        (List of patterns)[] 
    patternColor:
      type: string
      example: '#EAEAEA'
      description: |
        **A 6 or 8 hexadecimal shape color starting with a `#`.** *Example: #EAEAEA or #FF00FF55*

        _If no pattern is applied to the shape, this property will not change anything._
    overlayDirection:
      type: string
      enum:
        - horizontal
        - vertical
        - diagonal
      description: Direction of the overlay.
    overlayColor1:
      type: string
      description: First color of the overlay. 6-8 Digits Hexa color.
    overlayColor2:
      type: string
      description: Second color of the overlay. 6-8 Digits Hexa color.
    ratingScore:
      type: number
      minimum: 0
      maximum: 100
      description: |
        **Score of the rating on a scale of 100.** *Example: 50*

        _For instance, as rating is displayed as five-stars, 50 will give a 2.5/5 score._  
    ratingBackgroundColor:
      type: string
      description: |
        **The background color displayed behind all the stars.**

        6 or 8 hexadecimal colors starting with a **#**. _i.e. #EAEAEA or #FF00FF55_
    starColor:
      type: string
      description: |
        **The color of the filled stars.**

        6 or 8 hexadecimal colors starting with a **#**. _i.e. #EAEAEA or #FF00FF55_
    starMargin:
      type: number
      minimum: 0
      maximum: 100
      description: '**Margins in pixels between stars.** *Example: 60*'
    starDimension:
      type: number
      minimum: 4
      maximum: 400
      description: '**Size in pixels of one star.** *Example: 100*'
    illustrationType:
      type: string
      description: '**The illustration library used to retrieved the illustration name. Can be: undraw, feather, twemoji or material_icons.**.'
    illustrationFile:
      type: string
      description: '**The illustration name.**.'
    illustrationProperties:
      type: object
      properties:
        primary_color:
          type: string
          description: |
            **Color of the illustration** 

            *A 6 or 8 hexadecimal shape color starting with a **#**.** *Example: #EAEAEA or #FF00FF55_*
      description: |
        **Only `Undraw`, `feather` and `material icons` support `illustration_properties`.**
    qrcodeBackgroundColor:
      type: string
      description: |
        **The background color displayed behind the qrcode.**

        6 or 8 hexadecimal colors starting with a **#**. _i.e. #EAEAEA or #FF00FF55_
    qrcodeForegroundColor:
      type: string
      description: |
        **The color of the qrcode (of all squares).**

        6 or 8 hexadecimal colors starting with a **#**. _i.e. #EAEAEA or #FF00FF55_
    qrcodePayload:
      type: string
      description: |
        **The content of the qrcode. i.e. Lorem Ipsum**

        This content will be displayed once the QR Code is scanned.
    qrcodeImageUrl:
      type: string
      description: |
        **HTTP(s) URL of the icon displayed in the middle of the QR Code** *Example: https://www.abyssale.com/imge/abyssale_logo.png*

        __It must be a public accessible link and have a filesize of 10 mo maximum.__

        Supported files: jpeg, png, webp
    qrcodeHideIcon:
      type: boolean
      description: '`true`, `false`. If true it hides the icon in the middle of the QRCode.'
    videoUrl:
      type: string
      format: uri
      description: |
        **HTTP(s) URL of the video** *Example: https://www.abyssale.com/imge/this_an_example.mp4*

        __It must be a public accessible link and have a filesize of 100 mo maximum.__

        Supported files: mp4
