> ## Documentation Index
> Fetch the complete documentation index at: https://docs.surfais.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Request a scan

> Request an on-demand visibility scan for an own brand.

Queues a scan through the same rule the dashboard's manual scan uses: one scan queued or running per brand at a time (the check covers scans dated today, UTC; once it has finished, a new request the same day is accepted and uses the allowance again), the organisation's manual-scan allowance and purchased scan credits apply (unlimited tiers skip the check), and the scan runs as a manual scan. Completion is observable through the brand's `last_scan_changed_at` (and, for platform partners, the `scan.completed` webhook). Own brands only (400 `validation_error` with `details[].code = "own_brand_only"`). The brand's state is re-checked at the moment it is queued: an archived brand is 409 `brand_archived` and a brand with no active prompt is 409 `no_active_prompts` — either way nothing is queued and no credit is touched (a queued job for such a brand would reserve a manual-scan credit and then run nothing).



## OpenAPI

````yaml /api-reference/openapi.json post /orgs/{orgId}/brands/{brandId}/scan-requests
openapi: 3.1.0
info:
  title: Surfais API
  version: 1.0.0
  description: >-
    The Surfais API gives programmatic access to the AI-visibility data Surfais
    measures for your brands: organisations, brands and competitors, tracked
    prompts, per-run results and mentions, scores, share of voice and cited
    sources. It can also provision brands, manage prompts and competitors,
    request on-demand scans, and deliver signed webhooks when a scan completes
    or a score or sentiment threshold is crossed.


    Base URL: `https://api.surfais.com/v1`. Send your API key as a Bearer token
    (`Authorization: Bearer sfs_live_…`). Test keys (`sfs_test_…`) are rejected
    by the production API. Requests and responses are JSON: a success is `{
    "data": … }`, an error is `{ "error": { "code", "message" }, "request_id"
    }`.


    Guides for authentication, pagination, errors, rate limits, idempotency and
    webhooks are at https://docs.surfais.com/api/introduction.
  contact:
    name: Surfais support
    email: support@surfais.com
    url: https://docs.surfais.com/api/support
servers:
  - url: https://api.surfais.com/v1
    description: >-
      Production (the `/v1` prefix is part of the server URL; paths below are
      relative to it).
security:
  - bearerKey: []
tags:
  - name: orgs
    description: Organisations reachable by the key, their usage, and the partner link.
  - name: brands
    description: Own brands (properties) and competitor rows.
  - name: prompts
    description: 'Tracked prompts: reads, CRUD and the declarative sync.'
  - name: results
    description: Finalised run-level data.
  - name: scores
    description: Persisted scores, per-market history and share of voice.
  - name: sources
    description: Cited domains.
  - name: scans
    description: On-demand scan requests.
  - name: webhooks
    description: >-
      Outbound event delivery: endpoints, subscriptions, deliveries (partner
      keys).
externalDocs:
  description: Guides, concepts and webhooks
  url: https://docs.surfais.com/api/introduction
paths:
  /orgs/{orgId}/brands/{brandId}/scan-requests:
    post:
      tags:
        - scans
      summary: Request a scan
      description: >-
        Request an on-demand visibility scan for an own brand.


        Queues a scan through the same rule the dashboard's manual scan uses:
        one scan queued or running per brand at a time (the check covers scans
        dated today, UTC; once it has finished, a new request the same day is
        accepted and uses the allowance again), the organisation's manual-scan
        allowance and purchased scan credits apply (unlimited tiers skip the
        check), and the scan runs as a manual scan. Completion is observable
        through the brand's `last_scan_changed_at` (and, for platform partners,
        the `scan.completed` webhook). Own brands only (400 `validation_error`
        with `details[].code = "own_brand_only"`). The brand's state is
        re-checked at the moment it is queued: an archived brand is 409
        `brand_archived` and a brand with no active prompt is 409
        `no_active_prompts` — either way nothing is queued and no credit is
        touched (a queued job for such a brand would reserve a manual-scan
        credit and then run nothing).
      operationId: requestScan
      parameters:
        - in: path
          name: orgId
          schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            description: >-
              Organisation id. Org keys: the key's own org. Partner keys: any
              org with an active link. Anything else is 404.
          required: true
          description: >-
            Organisation id. Org keys: the key's own org. Partner keys: any org
            with an active link. Anything else is 404.
        - in: path
          name: brandId
          schema:
            type: string
            format: uuid
            pattern: >-
              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
            description: >-
              Brand id within the org (own brand or competitor row); 404 when
              not in the org. Writes that add tracking need an own (400
              `validation_error` with `details[].code = "own_brand_only"`),
              non-archived (409 `brand_archived`) brand.
          required: true
          description: >-
            Brand id within the org (own brand or competitor row); 404 when not
            in the org. Writes that add tracking need an own (400
            `validation_error` with `details[].code = "own_brand_only"`),
            non-archived (409 `brand_archived`) brand.
        - in: header
          name: Idempotency-Key
          schema:
            description: >-
              Optional. 1–255 characters, unique per intended write. Same key +
              same request → the stored response is replayed with
              `Idempotent-Replayed: true`; same key + different request → 409
              `idempotency_key_reuse`; still running → 409
              `idempotency_key_in_flight`. Outside that range → 400
              `validation_error` (`invalid_header`).
            type: string
            minLength: 1
            maxLength: 255
          description: >-
            Optional. 1–255 characters, unique per intended write. Same key +
            same request → the stored response is replayed with
            `Idempotent-Replayed: true`; same key + different request → 409
            `idempotency_key_reuse`; still running → 409
            `idempotency_key_in_flight`. Outside that range → 400
            `validation_error` (`invalid_header`).
      responses:
        '202':
          description: Queued.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
            Idempotent-Replayed:
              description: >-
                Present, as `true`, when this response was replayed from the
                Idempotency-Key store rather than executed.
              schema:
                description: >-
                  Present, as `true`, when this response was replayed from the
                  Idempotency-Key store rather than executed.
                type: string
                const: 'true'
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/ScanRequestAccepted'
                required:
                  - data
        '400':
          description: >-
            `validation_error` (with `details`), `invalid_json`, or the
            operation's own 400 (`text_immutable`, `duplicate_prompt_text`). An
            `Idempotency-Key` outside its length bounds is `validation_error`
            with `details[].path = "Idempotency-Key"`.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
            Idempotent-Replayed:
              description: >-
                Present, as `true`, when this response was replayed from the
                Idempotency-Key store rather than executed.
              schema:
                description: >-
                  Present, as `true`, when this response was replayed from the
                  Idempotency-Key store rather than executed.
                type: string
                const: 'true'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: '`invalid_api_key` — uniform for every authentication failure.'
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '402':
          description: >-
            `no_manual_scans` — no manual scans left this month and no purchased
            credits; `details` is the balance.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
            Idempotent-Replayed:
              description: >-
                Present, as `true`, when this response was replayed from the
                Idempotency-Key store rather than executed.
              schema:
                description: >-
                  Present, as `true`, when this response was replayed from the
                  Idempotency-Key store rather than executed.
                type: string
                const: 'true'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Stable machine code — see the error list in the
                          description.
                      message:
                        type: string
                      details:
                        $ref: '#/components/schemas/NoManualScans'
                    required:
                      - code
                      - message
                  request_id:
                    type: string
                    description: Echoed in the `X-Request-Id` header.
                required:
                  - error
                  - request_id
        '403':
          description: >-
            `tier_not_entitled` — the organisation's plan has no on-demand
            scans; or `write_scope_required` / `link_scope_insufficient`.
            Charged to the key's minute allowance, so the `X-RateLimit-*` trio
            is present.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
            Idempotent-Replayed:
              description: >-
                Present, as `true`, when this response was replayed from the
                Idempotency-Key store rather than executed.
              schema:
                description: >-
                  Present, as `true`, when this response was replayed from the
                  Idempotency-Key store rather than executed.
                type: string
                const: 'true'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '404':
          description: >-
            `not_found` — the org is not reachable by this key or a nested id is
            not in it. Raised after authentication and the minute charge, so it
            carries the `X-RateLimit-*` trio and is metered.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
            Idempotent-Replayed:
              description: >-
                Present, as `true`, when this response was replayed from the
                Idempotency-Key store rather than executed.
              schema:
                description: >-
                  Present, as `true`, when this response was replayed from the
                  Idempotency-Key store rather than executed.
                type: string
                const: 'true'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '409':
          description: >-
            `scan_already_queued` — a scan for this brand is already queued or
            running today; `details` is a `ScanAlreadyQueued` whose `job_id` may
            be null. `brand_archived` or `no_active_prompts` — `details` is a
            `BrandStateConflict`. `idempotency_key_reuse` /
            `idempotency_key_in_flight` carry no `details`.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
            Idempotent-Replayed:
              description: >-
                Present, as `true`, when this response was replayed from the
                Idempotency-Key store rather than executed.
              schema:
                description: >-
                  Present, as `true`, when this response was replayed from the
                  Idempotency-Key store rather than executed.
                type: string
                const: 'true'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        description: >-
                          Stable machine code — see the error list in the
                          description.
                      message:
                        type: string
                      details:
                        anyOf:
                          - $ref: '#/components/schemas/ScanAlreadyQueued'
                          - $ref: '#/components/schemas/BrandStateConflict'
                    required:
                      - code
                      - message
                  request_id:
                    type: string
                    description: Echoed in the `X-Request-Id` header.
                required:
                  - error
                  - request_id
        '413':
          description: '`payload_too_large` — the body exceeds 1 MB.'
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: >-
            `rate_limited` (per-minute limit, or too many failed authentications
            from this address) or `quota_exceeded`.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            Retry-After:
              required: true
              description: Seconds to wait before retrying — present on every 429 and 503.
              schema:
                type: string
                description: >-
                  Seconds to wait before retrying — present on every 429 and
                  503.
            X-RateLimit-Limit:
              required: true
              description: >-
                Requests allowed per minute for this key. On a 429
                `rate_limited` from the failed-authentication gate: failed
                attempts allowed per minute for the client address.
              schema:
                type: string
                description: >-
                  Requests allowed per minute for this key. On a 429
                  `rate_limited` from the failed-authentication gate: failed
                  attempts allowed per minute for the client address.
            X-RateLimit-Remaining:
              required: true
              description: >-
                Requests left in the current minute window (0 on the
                failed-authentication 429).
              schema:
                type: string
                description: >-
                  Requests left in the current minute window (0 on the
                  failed-authentication 429).
            X-RateLimit-Reset:
              required: true
              description: Unix seconds at which the current minute window ends.
              schema:
                type: string
                description: Unix seconds at which the current minute window ends.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '500':
          description: >-
            `internal_error` — quote `request_id`. A failure inside a route
            answers after the minute charge and carries the `X-RateLimit-*`
            trio; a failure before the limiter carries only `X-Request-Id`.
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            X-RateLimit-Limit:
              description: >-
                Present when the failure occurred after the minute charge
                (inside a route); absent on a failure before the limiter.
                Requests allowed per minute for this key.
              schema:
                description: >-
                  Present when the failure occurred after the minute charge
                  (inside a route); absent on a failure before the limiter.
                  Requests allowed per minute for this key.
                type: string
            X-RateLimit-Remaining:
              description: >-
                Present when the failure occurred after the minute charge.
                Requests left in the current minute window.
              schema:
                description: >-
                  Present when the failure occurred after the minute charge.
                  Requests left in the current minute window.
                type: string
            X-RateLimit-Reset:
              description: >-
                Present when the failure occurred after the minute charge. Unix
                seconds at which the current minute window ends.
              schema:
                description: >-
                  Present when the failure occurred after the minute charge.
                  Unix seconds at which the current minute window ends.
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '503':
          description: >-
            `api_unavailable` (switched off; `Retry-After` is 60),
            `rate_limit_unavailable` (fail-closed limiter — its store, or a
            saturated failed-authentication gate; before the minute charge, so
            no `X-RateLimit-*` trio), or `store_unavailable` (a tenant-store
            call behind an authenticated request exceeded 15000 ms — raised
            after the minute charge, so it is counted and carries the trio).
          headers:
            X-Request-Id:
              required: true
              description: >-
                Correlation id for this request; equals `request_id` in an error
                envelope.
              schema:
                type: string
                description: >-
                  Correlation id for this request; equals `request_id` in an
                  error envelope.
            Retry-After:
              required: true
              description: Seconds to wait before retrying — present on every 429 and 503.
              schema:
                type: string
                description: >-
                  Seconds to wait before retrying — present on every 429 and
                  503.
            X-RateLimit-Limit:
              description: >-
                Present when the failure occurred after the minute charge
                (inside a route); absent on a failure before the limiter.
                Requests allowed per minute for this key.
              schema:
                description: >-
                  Present when the failure occurred after the minute charge
                  (inside a route); absent on a failure before the limiter.
                  Requests allowed per minute for this key.
                type: string
            X-RateLimit-Remaining:
              description: >-
                Present when the failure occurred after the minute charge.
                Requests left in the current minute window.
              schema:
                description: >-
                  Present when the failure occurred after the minute charge.
                  Requests left in the current minute window.
                type: string
            X-RateLimit-Reset:
              description: >-
                Present when the failure occurred after the minute charge. Unix
                seconds at which the current minute window ends.
              schema:
                description: >-
                  Present when the failure occurred after the minute charge.
                  Unix seconds at which the current minute window ends.
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
components:
  schemas:
    ScanRequestAccepted:
      type: object
      properties:
        job_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: Id of the queued visibility scan job.
        idempotency_key:
          type: string
          description: >-
            The queue's own per-day key for this brand. While that scan is
            queued or running, a second request answers 409
            `scan_already_queued` with it; once it has finished, a new request
            on the same day is accepted.
        status:
          type: string
          const: queued
      required:
        - job_id
        - idempotency_key
        - status
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Stable machine code — see the error list in the description.
            message:
              type: string
            details: {}
          required:
            - code
            - message
        request_id:
          type: string
          description: Echoed in the `X-Request-Id` header.
      required:
        - error
        - request_id
    NoManualScans:
      type: object
      properties:
        manual_scans_remaining:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        scan_credits:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
      required:
        - manual_scans_remaining
        - scan_credits
    ScanAlreadyQueued:
      type: object
      properties:
        job_id:
          anyOf:
            - type: string
              format: uuid
              pattern: >-
                ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
              description: UUID.
            - type: 'null'
        idempotency_key:
          type: string
      required:
        - job_id
        - idempotency_key
    BrandStateConflict:
      type: object
      properties:
        brand_id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
          description: The own brand whose state refused the write.
      required:
        - brand_id
  securitySchemes:
    bearerKey:
      type: http
      scheme: bearer
      bearerFormat: sfs_live_… / sfs_test_…
      description: >-
        A Surfais API key — an organisation key or a partner key. Issued by
        Surfais; shown once. Rotate by creating a new key, then revoking the old
        one.

````