Plainrouter Creative API

The Creative API from Plainrouter — 4 operation(s) for creative.

Operations 5

POST /workspaces/{workspace}/admin/creatives Upload a creative #
GET /workspaces/{workspace}/admin/creatives List workspace creatives #
POST /workspaces/{workspace}/admin/creatives/from-url Store a creative from a URL #
PATCH /workspaces/{workspace}/admin/creatives/{creative}/status Update a workspace creative status #
GET /workspaces/{workspace}/admin/creatives/{creative} Read a workspace creative #

Work with this as data

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

MCP server

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

https://apis.io/mcp

Tools for apis

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

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/plainrouter:plainrouter-creative-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

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

Get an API key

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

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

OpenAPI Specification

plainrouter-creative-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Plainrouter Creative API
  version: 0.5.0
  description: 'Operations tagged Creative across 2 of this provider''s published API definitions: dev-plainrouter-openapi.json, plainrouter-openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://plainrouter.com/api/v1
  description: Production
security:
- workspaceSecret: []
tags:
- name: Creative
paths:
  /workspaces/{workspace}/admin/creatives:
    post:
      operationId: storeCreative
      description: Store a creative in the credential-bound workspace. Set generator, generator_job and parent_creative tags for output from an outside tool.
      summary: Upload a creative
      tags:
      - Creative
      parameters:
      - name: workspace
        in: path
        required: true
        description: The workspace ID
        schema:
          type: integer
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                file:
                  type: string
                  format: binary
                  description: JPEG, PNG, MP4 or QuickTime bytes, at most 4 GiB.
                tags:
                  type: object
                  description: Optional flat map of at most 32 string tags; reserved keys count toward the cap. For a creative from an outside tool, set generator and generator_job, plus parent_creative for a variation. Values are stored unchanged. PlainRouter’s own creative tools will set these on every creative they make; intake performs no generation, rendering or scoring.
                  properties:
                    generator:
                      type: string
                      description: Lowercase slug naming the outside tool that made the creative.
                      pattern: ^[a-z0-9-]{1,64}$
                      minLength: 1
                      maxLength: 64
                    generator_job:
                      type: string
                      description: Printable characters naming the tool’s job or render; control and other non-printable characters are refused.
                      minLength: 1
                      maxLength: 255
                    parent_creative:
                      type: string
                      description: 'The id returned by the creative APIs: a lowercase ULID of an existing creative in the same workspace that this creative varies.'
                      pattern: ^[0-7][0-9a-hjkmnp-tv-z]{25}$
                  additionalProperties:
                    type: string
                    maxLength: 255
                source_ref:
                  type:
                  - string
                  - 'null'
                  maxLength: 255
              required:
              - file
      responses:
        '201':
          description: Creative stored, or the existing creative returned for identical bytes in this workspace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreativeIntakeRead'
        '401':
          description: A valid workspace-bound credential is required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '403':
          description: The credential or workspace grant does not authorize creative intake.
          content:
            application/json:
              schema:
                anyOf:
                - $ref: '#/components/schemas/ErrorMessage'
                - $ref: '#/components/schemas/AgentCredentialError'
        '404':
          description: Creative intake is disabled, or the workspace is missing or inaccessible.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiRouteNotFound'
        '422':
          description: A reserved tag that violates the provenance contract returns error.code creative_provenance_invalid and error.message naming the key. Other intake refusals return their stable error.code and error.message; request-shape errors return message plus field errors.
          content:
            application/json:
              schema:
                anyOf:
                - $ref: '#/components/schemas/CreativeIntakeRejected'
                - $ref: '#/components/schemas/ValidationError'
        '413':
          description: Creative bytes exceed the 4 GiB cap, or POST data exceeds the request limit.
          content:
            application/json:
              schema:
                anyOf:
                - $ref: '#/components/schemas/CreativeIntakeRejected'
                - $ref: '#/components/schemas/ErrorMessage'
      security:
      - creativeWriter: []
    get:
      operationId: launch.creatives.index
      description: Read complete workspace creative rows within the shared MCP byte budget. Continue with next_cursor as cursor in the same workspace.
      summary: List workspace creatives
      tags:
      - Creative
      parameters:
      - name: workspace
        in: path
        required: true
        description: The workspace ID
        schema:
          type: integer
      - name: cursor
        in: query
        description: Continue using next_cursor with the same filters; rule lists use an immutable rule ID, other lists an offset or object ID.
        schema:
          type: integer
          minimum: 0
      - name: per_page
        in: query
        description: Maximum complete rows; the byte budget may return fewer. Defaults to 25.
        schema:
          type: integer
          default: 25
          minimum: 1
          maximum: 100
      - name: page
        in: query
        description: Integer page from 1 through 10000000000000000; integer strings are accepted. Zero, negatives, fractions, non-numeric strings and booleans return 422 with a page field validation error.
        schema:
          type: integer
          default: 1
          minimum: 1
          maximum: 10000000000000000
      responses:
        '401':
          description: Invalid or missing Server secret.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '200':
          description: Bounded rows; no nested history is included in rule summaries. Result projections share the 80,000-byte MCP JSON budget; defaults are bounded, next_cursor continues complete rows, and oversized single rows are explicitly refused. Plan creative continuation uses the read endpoint; proposal continuation uses the batch read endpoint.
          content:
            application/json:
              schema:
                type: object
                properties:
                  creatives:
                    type: object
                    description: Complete projection rows are paged within 80,000 JSON bytes, accounting for both MCP representations. Defaults are bounded. Follow next_cursor with the same scope and filters. One oversized row is explicitly refused; fields are never silently clipped.
                    properties:
                      data:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                              pattern: ^[0-7][0-9a-hjkmnp-tv-z]{25}$
                            fingerprint:
                              type: string
                            type:
                              type: string
                              enum:
                              - image
                              - video
                            mime_type:
                              type: string
                            byte_size:
                              type: integer
                            width:
                              type:
                              - integer
                              - 'null'
                            height:
                              type:
                              - integer
                              - 'null'
                            aspect_ratio:
                              type:
                              - number
                              - 'null'
                            duration_ms:
                              type:
                              - integer
                              - 'null'
                            original_filename:
                              type:
                              - string
                              - 'null'
                            source_ref:
                              type:
                              - string
                              - 'null'
                            tags:
                              description: Stored tags, including provenance when supplied. An empty map is returned as an empty array. Existing creatives keep their original tags.
                              anyOf:
                              - type: object
                                additionalProperties:
                                  type: string
                              - type: array
                                items:
                                  type: string
                                maxItems: 0
                            status:
                              type: string
                              enum:
                              - draft
                              - approved
                              - retired
                            created_at:
                              type:
                              - string
                              - 'null'
                            updated_at:
                              type:
                              - string
                              - 'null'
                          required:
                          - id
                          - fingerprint
                          - type
                          - mime_type
                          - byte_size
                          - width
                          - height
                          - aspect_ratio
                          - duration_ms
                          - source_ref
                          - tags
                          - status
                          - created_at
                          - updated_at
                      total:
                        type: integer
                      per_page:
                        type: integer
                      next_cursor:
                        type:
                        - integer
                        - 'null'
                      truncated:
                        type: boolean
                      continuation:
                        type: string
                required:
                - creatives
        '404':
          description: A disabled Creative surface or missing workspace returns the api_route_not_found envelope with error, request and resources.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiRouteNotFound'
        '422':
          description: JSON booleans in integer inputs, including workspace selectors, return message plus errors mapping field names to arrays of messages. Numeric strings retain their existing validation and coercion.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '403':
          description: The workspace grant does not authorize this operation, or the token cannot access this workspace. Returns message.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
    servers:
    - url: https://plainrouter.com/api/v1
      description: Production
  /workspaces/{workspace}/admin/creatives/from-url:
    post:
      operationId: storeCreativeFromUrl
      description: Store a creative in the credential-bound workspace. Set generator, generator_job and parent_creative tags for output from an outside tool.
      summary: Store a creative from a URL
      tags:
      - Creative
      parameters:
      - name: workspace
        in: path
        required: true
        description: The workspace ID
        schema:
          type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                url:
                  type: string
                  description: Vetted HTTPS URL to fetch; private addresses and unsafe redirects are refused.
                  maxLength: 2048
                tags:
                  type: object
                  description: Optional flat map of at most 32 string tags; reserved keys count toward the cap. For a creative from an outside tool, set generator and generator_job, plus parent_creative for a variation. Values are stored unchanged. PlainRouter’s own creative tools will set these on every creative they make; intake performs no generation, rendering or scoring.
                  properties:
                    generator:
                      type: string
                      description: Lowercase slug naming the outside tool that made the creative.
                      pattern: ^[a-z0-9-]{1,64}$
                      minLength: 1
                      maxLength: 64
                    generator_job:
                      type: string
                      description: Printable characters naming the tool’s job or render; control and other non-printable characters are refused.
                      minLength: 1
                      maxLength: 255
                    parent_creative:
                      type: string
                      description: 'The id returned by the creative APIs: a lowercase ULID of an existing creative in the same workspace that this creative varies.'
                      pattern: ^[0-7][0-9a-hjkmnp-tv-z]{25}$
                  additionalProperties:
                    type: string
                    maxLength: 255
                source_ref:
                  type:
                  - string
                  - 'null'
                  maxLength: 255
              required:
              - url
      responses:
        '201':
          description: Creative stored, or the existing creative returned for identical bytes in this workspace.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreativeIntakeRead'
        '401':
          description: A valid workspace-bound credential is required.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '403':
          description: The credential or workspace grant does not authorize creative intake.
          content:
            application/json:
              schema:
                anyOf:
                - $ref: '#/components/schemas/ErrorMessage'
                - $ref: '#/components/schemas/AgentCredentialError'
        '404':
          description: Creative intake is disabled, or the workspace is missing or inaccessible.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiRouteNotFound'
        '422':
          description: A reserved tag that violates the provenance contract returns error.code creative_provenance_invalid and error.message naming the key. Other intake refusals return their stable error.code and error.message; request-shape errors return message plus field errors.
          content:
            application/json:
              schema:
                anyOf:
                - $ref: '#/components/schemas/CreativeIntakeRejected'
                - $ref: '#/components/schemas/ValidationError'
        '413':
          description: Creative bytes exceed the 4 GiB cap, or POST data exceeds the request limit.
          content:
            application/json:
              schema:
                anyOf:
                - $ref: '#/components/schemas/CreativeIntakeRejected'
                - $ref: '#/components/schemas/ErrorMessage'
      security:
      - creativeWriter: []
    servers:
    - url: https://plainrouter.com/api/v1
      description: Production
  /workspaces/{workspace}/admin/creatives/{creative}/status:
    patch:
      operationId: launch.creatives.status
      description: Read a creative or change its approval status within the authorized workspace. Creative content and provider submission remain separate operations.
      summary: Update a workspace creative status
      tags:
      - Creative
      parameters:
      - name: workspace
        in: path
        required: true
        description: The workspace ID
        schema:
          type: integer
      - name: creative
        in: path
        required: true
        schema:
          type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCreativeStatusRequest'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  creative:
                    type: array
                    items: {}
                required:
                - creative
        '401':
          description: Invalid or missing Server secret.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '404':
          description: A missing workspace returns the api_route_not_found envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiRouteNotFound'
        '422':
          description: JSON booleans in integer inputs, including workspace selectors, return message plus errors mapping field names to arrays of messages. Numeric strings retain their existing validation and coercion.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
    servers:
    - url: https://plainrouter.com/api/v1
      description: Production
  /workspaces/{workspace}/admin/creatives/{creative}:
    get:
      operationId: launch.creatives.show
      description: Read a creative or change its approval status within the authorized workspace. Creative content and provider submission remain separate operations.
      summary: Read a workspace creative
      tags:
      - Creative
      parameters:
      - name: workspace
        in: path
        required: true
        description: The workspace ID
        schema:
          type: integer
      - name: creative
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  creative:
                    type: array
                    items: {}
                required:
                - creative
        '401':
          description: Invalid or missing Server secret.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '404':
          description: A missing workspace returns the api_route_not_found envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiRouteNotFound'
        '422':
          description: JSON booleans in integer inputs, including workspace selectors, return message plus errors mapping field names to arrays of messages. Numeric strings retain their existing validation and coercion.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
    servers:
    - url: https://plainrouter.com/api/v1
      description: Production
components:
  schemas:
    CreativeIntakeRejected:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
          required:
          - code
          - message
      required:
      - error
      title: CreativeIntakeRejected
    CreativeIntakeRead:
      type: object
      properties:
        creative:
          type: object
          properties:
            id:
              type: string
              pattern: ^[0-7][0-9a-hjkmnp-tv-z]{25}$
            fingerprint:
              type: string
            type:
              type: string
              enum:
              - image
              - video
            mime_type:
              type: string
            byte_size:
              type: integer
            width:
              type:
              - integer
              - 'null'
            height:
              type:
              - integer
              - 'null'
            aspect_ratio:
              type:
              - number
              - 'null'
            duration_ms:
              type:
              - integer
              - 'null'
            original_filename:
              type:
              - string
              - 'null'
            source_ref:
              type:
              - string
              - 'null'
            tags:
              description: Stored tags, including provenance when supplied. An empty map is returned as an empty array. Existing creatives keep their original tags.
              anyOf:
              - type: object
                additionalProperties:
                  type: string
              - type: array
                items:
                  type: string
                maxItems: 0
            status:
              type: string
              enum:
              - draft
              - approved
              - retired
            created_at:
              type:
              - string
              - 'null'
            updated_at:
              type:
              - string
              - 'null'
          required:
          - id
          - fingerprint
          - type
          - mime_type
          - byte_size
          - width
          - height
          - aspect_ratio
          - duration_ms
          - source_ref
          - tags
          - status
          - created_at
          - updated_at
      required:
      - creative
      title: CreativeIntakeRead
    AgentCredentialError:
      type: object
      properties:
        error:
          type: string
          enum:
          - invalid_token
          - insufficient_scope
        error_description:
          type: string
      required:
      - error
      - error_description
      title: AgentCredentialError
    ApiRouteNotFound:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
              - api_route_not_found
            message:
              type: string
            resolution:
              type: string
          required:
          - code
          - message
          - resolution
        request:
          type: object
          properties:
            method:
              type: string
            path:
              type: string
          required:
          - method
          - path
        resources:
          type: object
          properties:
            documentation:
              type: string
            openapi:
              type: string
          required:
          - documentation
          - openapi
      required:
      - error
      - request
      - resources
      title: ApiRouteNotFound
    ValidationError:
      type: object
      properties:
        message:
          type: string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
      required:
      - message
      - errors
      title: ValidationError
    ErrorMessage:
      type: object
      properties:
        message:
          type: string
      required:
      - message
      title: ErrorMessage
    UpdateCreativeStatusRequest:
      type: object
      properties:
        status:
          type: string
          enum:
          - draft
          - approved
          - retired
      required:
      - status
      title: UpdateCreativeStatusRequest
  securitySchemes:
    workspaceSecret:
      type: http
      description: Per-workspace Server secret. It authenticates only the Signals workspace represented by the credential.
      scheme: bearer
    sandboxCredential:
      type: http
      description: Short-lived Sandbox key issued by POST /sandbox/keys.
      scheme: bearer
    workspaceActionKey:
      type: http
      description: Workspace key with read-actions for reads or propose-actions for writes. Unbound keys select an available advertising account with account_id.
      scheme: bearer
    planWriter:
      type: http
      description: An OAuth agent or account-bound Workspace Key with write access and the plan-create grant.
      scheme: bearer
    workspaceInventoryKey:
      type: http
      description: Workspace read key with the get_inventory_metrics grant. Account-bound keys can read only their bound account.
      scheme: bearer
    planReader:
      type: http
      description: An OAuth agent or account-bound Workspace Key with read access to the approved ad account.
      scheme: bearer
    creativeWriter:
      type: http
      description: Workspace-bound write credential with a grant authorizing creative intake.
      scheme: bearer
    testReader:
      type: http
      description: A workspace principal with read tier and the launch.plans.index and launch.plans.show grants for this account.
      scheme: bearer
    testWriter:
      type: http
      description: A workspace principal with write tier and the launch.plans.store grant for this account.
      scheme: bearer
    ruleReader:
      type: http
      description: 'A workspace-scoped key with read ability and actions.rules.index or actions.rules.show access to the bound account. Send Accept: application/json.'
      scheme: bearer
    ruleWriter:
      type: http
      description: 'A workspace-scoped key with write ability and the actions.rules.store or actions.rules.update grant. Send Accept: application/json.'
      scheme: bearer
    agentContextKey:
      type: http
      description: Workspace key with read ability, ad-account.read permission and the agent.context grant.
      scheme: bearer
    agentContextOAuth:
      type: oauth2
      description: OAuth access token for an active approved agent principal with mcp:use, ad-account.read and agent.context authorization. Authorization code with PKCE and device authorization tokens are accepted. This scheme applies only to agent context.
      flows:
        authorizationCode:
          authorizationUrl: https://plainrouter.com/oauth2/authorize
          tokenUrl: https://plainrouter.com/oauth2/token
          refreshUrl: https://plainrouter.com/oauth2/token
          scopes:
            mcp:use: Use the approved agent principal.
x-refined-from:
- dev-plainrouter-openapi.json
- plainrouter-openapi.json
x-action-types:
- increase_budget
- decrease_budget
- pause
- resume
- replace_creative
- shift_spend
- rollback
- create_campaign
- create_ad_set
- create_ad
- upload_asset
x-signed: true