# Brick Work API v2: the contract of the whole surface (M.11a, issue #113). Generated in step with api-v2.md.
# x-piece says which piece implements an operation (M.11a to M.11d); x-v1 names the v1 operation it replaces.
# An operation of a piece that has not landed answers 501 not_implemented (scripts/check_api_contract.py lists them).
openapi: 3.1.0
info:
  title: Brick Work API
  version: 2.0.0-draft
  summary: 'API v2 for the 4.0 line: v1''s resource set, envelopes and conventions with the 4.0 identity (design 7).'
  description: 'The contract of the whole v2 surface (M.11a, issue #113); a piece implements its operations against this file (`x-piece`). An operation
    whose piece has not landed answers 501 not_implemented. Items are addressed by Brick Work id (`/items/{id}`, install-local: store numbers, not ids)
    or by provider number (`/sets|parts|minifigures/by-number/{no}`, `/lookup`); bodies carry both. Conventions are api-v2.md. No per-token rate limit.
    Stored hashed tokens with scopes read, write, admin, plus BW_API_TOKEN as an environment bootstrap. Writes are one transaction plus an event with via=api
    and actor=token name and are undoable through POST /events/{id}/undo.'
x-error-status:
  moved: 307
  bad_request: 400
  unknown_filter: 400
  unauthorized: 401
  forbidden: 403
  read_only_instance: 403
  not_found: 404
  method_not_allowed: 405
  ambiguous: 409
  archived: 409
  conflict: 409
  idempotency_conflict: 409
  merged: 409
  not_undoable: 409
  stale_match: 409
  undo_blocked: 409
  api_retired: 410
  precondition_failed: 412
  payload_too_large: 413
  unsupported_media_type: 415
  unidentified: 422
  unsupported_setting: 422
  validation_failed: 422
  catalogue_not_loaded: 424
  source_disabled: 424
  source_not_configured: 424
  idempotency_key_required: 428
  budget_exhausted: 429
  source_throttled: 429
  too_many_attempts: 429
  internal_error: 500
  not_implemented: 501
  source_error: 502
  api_disabled: 503
  db_unavailable: 503
  not_set_up: 503
servers:
- url: /api/v2
  description: Relative to the app origin.
security:
- bearerAuth:
  - read
tags:
- name: Meta
- name: Catalogue
- name: Items
- name: Identity
- name: Images
- name: Copies
- name: Copy parts
- name: Loose stock
- name: Minifigures
- name: Instructions
- name: Prices
- name: Wishlist
- name: Storages
- name: Lots
- name: Places
- name: Flags
- name: Planning
- name: Orders
- name: Events
- name: Jobs
- name: Sources
- name: Settings
- name: Admin
- name: Matching
- name: Tokens
x-m3-receipts:
  storage: 'One events row per M3 request: entity bw_api, field op:<key> (receipt without a key). new_value contains method, path, body_sha256, status,
    response, event_id, token_name and embedded core receipts. Undo rows also contain undone_event_id and have no Undo of their own.'
  dispatch: Embedded receipts are passed to collection.undo, add.undo, workbench.undo, ledger.undo and planning.undo. Standalone core and token receipts
    remain supported; token Undo requires admin.
  pagination: Events and jobs use SQL keysets on id (descending by default). Current prices use rowid keysets (ascending by default). Price history uses
    id keysets (descending by default); item-price summaries include the latest 200 records. Page totals are null for these growing histories.
x-mcp:
  milestone: M.11e
  transports:
  - stdio
  - streamable-http
  http-path: /mcp
  results: Single reads return data; lists retain page cursors; writes retain API receipts; API errors set isError.
  idempotency: Optional idempotency_key is forwarded; otherwise a UUID is generated. Retries must reuse the same key.
  hosting: ASGI host mounts SDK /mcp alongside the Flask WSGI routes; plain WSGI does not serve MCP.
  write-gate: allow-write and API write scope; checked again on every call
  resources:
    brickwork://summary: get_statistics
    brickwork://copies/{id}: get_copies_by_id
    brickwork://wishlist: get_wishes
    brickwork://storages: get_storages
    brickwork://sources: get_sources
    brickwork://events/recent: get_events
    brickwork://openapi: get_openapi_yaml
    brickwork://items/{provider}/{kind}/{no}:
      operation: get_lookup
      query:
        provider: '{provider}'
        kind: '{kind}'
        key: '{no}'
  tools-take: Numbers and a provider, never a Brick Work id (decision 7). Tool names stay where the v2 operation exists.
  item-rule: A path parameter marked x-mcp-item is an item id. The tool takes provider (bricklink by default), kind and no instead and looks the item
    up with GET /lookup before the call; a 404 or 409 ambiguous from the lookup is the tool's error. A schema marked x-mcp-item key is an ItemKey; the
    tool takes it as provider, kind and key, never as id.
paths:
  /wishlists:
    get:
      operationId: get_wishlists
      x-mcp-tool: get_wishlists
      summary: get wishlists
      description: The wishlists in their order (`sort`, name); `archived=true` includes the archived ones.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - name: archived
        in: query
        schema:
          type: boolean
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfWishlist'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_wishlists
      x-piece: M.11b
    post:
      operationId: post_wishlists
      x-mcp-tool: create_wishlist
      summary: Create a wishlist
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      responses:
        '201':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWishlist'
        default:
          $ref: '#/components/responses/Problem'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WishlistCreate'
      x-v1: post_wishlists
      x-piece: M.11c
  /wishlists/{id}:
    patch:
      operationId: patch_wishlists_by_id
      x-mcp-tool: edit_wishlist
      summary: Rename a wishlist or change its settings
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWishlist'
        default:
          $ref: '#/components/responses/Problem'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WishlistPatch'
      x-v1: patch_wishlists_id
      x-piece: M.11c
    delete:
      operationId: delete_wishlists_by_id
      x-mcp-tool: archive_wishlist
      summary: Archive a wishlist
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWishlist'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_wishlists_id
      x-piece: M.11c
  /wishlists/{id}/restore:
    post:
      operationId: post_wishlists_by_id_restore
      x-mcp-tool: restore_wishlist
      summary: Restore an archived wishlist
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWishlist'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_wishlists_id_restore
      x-piece: M.11c
  /wishlists/{id}/transfer:
    post:
      operationId: post_wishlists_by_id_transfer
      x-mcp-tool: transfer_wishes
      summary: Move or copy wishes into this wishlist
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        default:
          $ref: '#/components/responses/Problem'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WishlistTransfer'
      x-v1: post_wishlists_id_transfer
      x-piece: M.11c
  /wishlists/{id}/export.xml:
    get:
      operationId: get_wishlists_by_id_export_xml
      x-mcp-tool: export_wishlist_xml
      summary: Export wishlist as BrickLink wanted list XML
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - read
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: kind
        in: query
        schema:
          type: string
          enum:
          - sets
          - parts
          default: parts
      - name: summary
        in: query
        schema:
          type: boolean
        description: Return content and download summary as JSON. id=all exports every active list.
      responses:
        '200':
          description: OK
          content:
            application/xml:
              schema:
                type: string
            application/json:
              schema:
                type: object
        default:
          $ref: '#/components/responses/Problem'
      x-v1: export_wishlist_xml
      x-piece: M.11b
  /wishlists/{id}/export.csv:
    get:
      operationId: get_wishlists_by_id_export_csv
      x-mcp-tool: export_wishlist_csv
      summary: Export wishlist as Rebrickable CSV
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - read
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: kind
        in: query
        schema:
          type: string
          enum:
          - sets
          - parts
          default: parts
      - name: summary
        in: query
        schema:
          type: boolean
        description: Return content and download summary as JSON. id=all exports every active list.
      responses:
        '200':
          description: OK
          content:
            text/csv:
              schema:
                type: string
            application/json:
              schema:
                type: object
        default:
          $ref: '#/components/responses/Problem'
      x-v1: export_wishlist_csv
      x-piece: M.11b
  /health:
    get:
      operationId: get_health
      summary: Liveness, schema and API version. No token.
      tags:
      - Meta
      security: []
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneHealth'
        '503':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_health
      x-piece: M.11a
  /version:
    get:
      operationId: get_version
      summary: Build, API and schema versions, enabled features.
      tags:
      - Meta
      security:
      - bearerAuth:
        - read
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneVersion'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '503':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_version
      x-piece: M.11a
  /openapi.yaml:
    get:
      operationId: get_openapi_yaml
      summary: This contract as OpenAPI 3.1 YAML. No token.
      tags:
      - Meta
      security: []
      responses:
        '200':
          description: File.
          content:
            application/yaml:
              schema:
                type: string
                format: binary
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_openapi_yaml
      x-piece: M.11a
  /me:
    get:
      operationId: get_me
      summary: 'The calling token: name, scopes, expiry.'
      tags:
      - Meta
      security:
      - bearerAuth:
        - read
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneMe'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '503':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_me
      x-piece: M.11a
  /catalogue/items:
    get:
      operationId: get_catalogue_items
      x-mcp-tool: search_catalogue
      summary: Search the local BrickLink catalogue file by type and text.
      tags:
      - Catalogue
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Q_sort'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfCatalogueItem'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_catalogue_items
      x-piece: M.11b
  /catalogue/items/{id}:
    get:
      operationId: get_catalogue_items_by_id
      summary: One catalogue entry.
      tags:
      - Catalogue
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneCatalogueItem'
        '404':
          $ref: '#/components/responses/NotFound'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_catalogue_items_by_type_by_no
      x-piece: M.11b
  /catalogue/status:
    get:
      operationId: get_catalogue_status
      summary: Catalogue file state (loaded, item counts, imported_at).
      tags:
      - Catalogue
      security:
      - bearerAuth:
        - read
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneCatalogueStatus'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_catalogue_status
      x-piece: M.11b
  /colors:
    get:
      operationId: get_colors
      summary: All colours.
      tags:
      - Catalogue
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfColor'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_colors
      x-piece: M.11b
  /colors/{color_id}:
    get:
      operationId: get_colors_by_color_id
      summary: One colour.
      tags:
      - Catalogue
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_color_id_int'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneColor'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_colors_by_color_id
      x-piece: M.11b
  /items:
    get:
      operationId: get_items
      summary: Items known to the store, with text search over name, number and properties.
      tags:
      - Items
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Q_theme'
      - $ref: '#/components/parameters/Q_category'
      - $ref: '#/components/parameters/Q_year'
      - $ref: '#/components/parameters/Q_owned'
      - $ref: '#/components/parameters/Q_sort'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfItem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items
      x-piece: M.11b
  /items/{id}:
    get:
      operationId: get_items_by_id
      x-mcp-tool: get_item
      summary: 'The item: its Brick Work id, kind, name, the BrickLink numbers it is known by and its Rebrickable key (design 7). A merged id answers 307
        to the survivor.'
      tags:
      - Items
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      responses:
        '200':
          description: The item.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItem'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items_by_type_by_no
      x-piece: M.11a
  /items/{id}/inventory:
    get:
      operationId: get_items_by_id_inventory
      summary: Parts and figures the item is made of (inventory lines).
      tags:
      - Items
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfInventoryLine'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items_by_type_by_no_inventory
      x-piece: M.11b
  /items/{id}/used-in:
    get:
      operationId: get_items_by_id_used_in
      summary: Owned copies that contain this part or figure.
      tags:
      - Items
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfUsedIn'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items_by_type_by_no_used_in
      x-piece: M.11b
  /items/{id}/colors:
    get:
      operationId: get_items_by_id_colors
      summary: Colours this part is known in.
      tags:
      - Items
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfColor'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items_by_type_by_no_colors
      x-piece: M.11b
  /items/{id}/images:
    get:
      operationId: get_items_by_id_images
      summary: Local pictures of the item.
      tags:
      - Items
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfImage'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items_by_type_by_no_images
      x-piece: M.11b
  /items/{id}/import:
    post:
      operationId: post_items_by_id_import
      x-mcp-tool: import_item
      summary: Create the item identity and queue the six import steps.
      tags:
      - Items
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImportRequest'
      responses:
        '202':
          description: Accepted. The job runs in the background; poll GET /jobs/{id}.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJob'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_items_by_type_by_no_import
      x-piece: M.11d
  /images/{id}/content:
    get:
      operationId: get_images_by_id_content
      summary: Image bytes from the local picture store.
      tags:
      - Images
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_image_id'
      responses:
        '200':
          description: File.
          content:
            image/*:
              schema:
                type: string
                format: binary
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_images_by_id_content
      x-piece: M.11b
  /copies:
    get:
      operationId: get_copies
      x-mcp-tool: list_copies
      summary: Owned set copies.
      tags:
      - Copies
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_number'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_condition'
      - $ref: '#/components/parameters/Q_status'
      - $ref: '#/components/parameters/Q_storage'
      - $ref: '#/components/parameters/Q_place'
      - $ref: '#/components/parameters/Q_flag'
      - $ref: '#/components/parameters/Q_lot'
      - $ref: '#/components/parameters/Q_problem'
      - $ref: '#/components/parameters/Q_duplicates'
      - $ref: '#/components/parameters/Q_theme'
      - $ref: '#/components/parameters/Q_year'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Q_sort'
      - $ref: '#/components/parameters/Q_archived'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfCopy'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies
      x-piece: M.11b
    post:
      operationId: post_copies
      x-mcp-tool: add_copies
      summary: Add owned copies of a set (quantity N makes N copies) and queue its import.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyCreate'
      responses:
        '200':
          description: Skipped. The client asked for decision=skip and the item is already owned or wished; nothing was written, event_id is null.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSkipped'
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCreated'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_copies
      x-piece: M.11c
  /copies/{id}:
    get:
      operationId: get_copies_by_id
      x-mcp-tool: get_copy
      summary: One copy.
      tags:
      - Copies
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneCopy'
          headers:
            ETag:
              schema:
                type: string
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies_by_id
      x-piece: M.11b
    patch:
      operationId: patch_copies_by_id
      x-mcp-tool: update_copy
      summary: Edit condition, completeness, storage, purchase and estimate fields, note.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      - $ref: '#/components/parameters/IfMatch'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_copies_by_id
      x-piece: M.11c
    delete:
      operationId: delete_copies_by_id
      x-mcp-tool: archive_copy
      summary: Archive the copy (the UI calls this deleting a set).
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      - $ref: '#/components/parameters/IfMatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_copies_by_id
      x-piece: M.11c
  /copies/{id}/restore:
    post:
      operationId: post_copies_by_id_restore
      summary: Clear the archive mark.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_copies_by_id_restore
      x-piece: M.11c
  /copies/{id}/flags:
    put:
      operationId: put_copies_by_id_flags
      summary: Replace the copy flags.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlagSet'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_copies_by_id_flags
      x-piece: M.11c
  /copies/{id}/pin:
    put:
      operationId: put_copies_by_id_pin
      summary: Pin or unpin a copy.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Pin'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_copies_by_id_pin
      x-piece: M.11c
  /copies/{id}/completeness:
    get:
      operationId: get_copies_by_id_completeness
      x-mcp-tool: get_copy_completeness
      summary: Stored and derived completeness, checked flag, missing and damaged counts.
      tags:
      - Copies
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneCompleteness'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies_by_id_completeness
      x-piece: M.11b
  /copies/{id}/checked:
    put:
      operationId: put_copies_by_id_checked
      x-mcp-tool: set_copy_checked
      summary: Set or clear the "Set is checked" flag and recompute derived completeness.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Checked'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCompleteness'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_copies_by_id_checked
      x-piece: M.11c
  /copies/{id}/check:
    get:
      operationId: get_copies_by_id_check
      summary: Part-check session state for this copy.
      tags:
      - Copies
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneCheckState'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies_by_id_check
      x-piece: M.11b
    post:
      operationId: post_copies_by_id_check
      summary: Apply one part-check action (start, answer, found_one, skip, select, back, next, spares, recheck, finish, undo).
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CheckAction'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCheckState'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_copies_by_id_check
      x-piece: M.11c
  /copies/{id}/gaps:
    get:
      operationId: get_copies_by_id_gaps
      summary: Missing, damaged and absent items of the copy.
      tags:
      - Copies
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfGap'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies_by_id_gaps
      x-piece: M.11b
  /copies/{id}/matches:
    get:
      operationId: get_copies_by_id_matches
      summary: Loose stock that would fill the copy gaps.
      tags:
      - Copies
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfMatch'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies_by_id_matches
      x-piece: M.11b
  /copies/{id}/take:
    post:
      operationId: post_copies_by_id_take
      x-mcp-tool: take_for_gap
      summary: Take N of one missing part (with its colour) or whole minifigure from loose stock into the copy; one Undo reverses every move.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Take'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_copies_by_id_take
      x-piece: M.11c
  /copies/{id}/parts:
    get:
      operationId: get_copies_by_id_parts
      x-mcp-tool: list_copy_parts
      summary: Part lines of the copy (required, spare, figure components).
      tags:
      - Copy parts
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_spare'
      - $ref: '#/components/parameters/Q_parent'
      - $ref: '#/components/parameters/Q_problem'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfCopyPart'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies_by_id_parts
      x-piece: M.11b
  /copies/{id}/parts/{part_id}:
    patch:
      operationId: patch_copies_by_id_parts_by_part_id
      x-mcp-tool: set_part_missing
      summary: Set missing, damaged, checked for one line (mark missing or found).
      tags:
      - Copy parts
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_part_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyPartPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopyPart'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_copies_by_id_parts_by_part_id
      x-piece: M.11c
  /copies/{id}/parts/bulk:
    post:
      operationId: post_copies_by_id_parts_bulk
      summary: Apply missing counts to many lines by item and colour (mode set or add, optional dry run).
      tags:
      - Copy parts
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyPartBulk'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenBulkResult'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_copies_by_id_parts_bulk
      x-piece: M.11c
  /copies/{id}/figures:
    get:
      operationId: get_copies_by_id_figures
      x-mcp-tool: list_copy_figures
      summary: Whole figures of the copy.
      tags:
      - Copy parts
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfCopyFigure'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_copies_by_id_figures
      x-piece: M.11b
  /copies/{id}/figures/{item_id}:
    patch:
      operationId: patch_copies_by_id_figures_by_item_id
      x-mcp-tool: set_figure_missing
      summary: Set the missing count of one whole figure.
      tags:
      - Copy parts
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_figure_item_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyFigurePatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopyFigure'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_copies_by_id_figures_by_type_by_no
      x-piece: M.11c
  /stock:
    get:
      operationId: get_stock
      x-mcp-tool: list_stock
      summary: Loose stock lines (parts, minifigures, booklets, anything).
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_number'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_condition'
      - $ref: '#/components/parameters/Q_storage'
      - $ref: '#/components/parameters/Q_lot'
      - $ref: '#/components/parameters/Q_place'
      - $ref: '#/components/parameters/Q_flag'
      - $ref: '#/components/parameters/Q_problem'
      - $ref: '#/components/parameters/Q_theme'
      - $ref: '#/components/parameters/Q_year'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Q_sort'
      - $ref: '#/components/parameters/Q_archived'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfStock'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_stock
      x-piece: M.11b
    post:
      operationId: post_stock
      x-mcp-tool: add_stock
      summary: Add loose stock; identical lines merge.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StockCreate'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCreated'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_stock
      x-piece: M.11c
  /stock/{id}:
    get:
      operationId: get_stock_by_id
      summary: One stock line.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneStock'
          headers:
            ETag:
              schema:
                type: string
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_stock_by_id
      x-piece: M.11b
    patch:
      operationId: patch_stock_by_id
      x-mcp-tool: update_stock
      summary: Edit a stock line (may merge into an existing line; response lists merged ids).
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      - $ref: '#/components/parameters/IfMatch'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StockPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStock'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_stock_by_id
      x-piece: M.11c
    delete:
      operationId: delete_stock_by_id
      summary: Archive the line.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      - $ref: '#/components/parameters/IfMatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStock'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_stock_by_id
      x-piece: M.11c
  /stock/{id}/restore:
    post:
      operationId: post_stock_by_id_restore
      summary: Clear the archive mark.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStock'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_stock_by_id_restore
      x-piece: M.11c
  /stock/{id}/flags:
    put:
      operationId: put_stock_by_id_flags
      summary: Replace the line flags.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlagSet'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStock'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_stock_by_id_flags
      x-piece: M.11c
  /stock/{id}/parts:
    get:
      operationId: get_stock_by_id_parts
      summary: Parts of a loose minifigure.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfLooseFigurePart'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_stock_by_id_parts
      x-piece: M.11b
    patch:
      operationId: patch_stock_by_id_parts
      summary: Set missing and damaged on parts of a loose minifigure.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LooseFigurePartPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenLooseFigureParts'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_stock_by_id_parts
      x-piece: M.11c
  /stock/{id}/give:
    post:
      operationId: post_stock_by_id_give
      x-mcp-tool: give_from_stock
      summary: Give N from this line to a copy gap or a loose-figure part gap.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Give'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_stock_by_id_give
      x-piece: M.11c
  /stock/booklets:
    post:
      operationId: post_stock_booklets
      summary: Add loose booklets from lines "set number, quantity".
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Booklets'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_stock_booklets
      x-piece: M.11c
  /found:
    post:
      operationId: post_found
      summary: Record found parts into copies, a loose line, or a list.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Found'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_found
      x-piece: M.11c
  /minifigures:
    get:
      operationId: get_minifigures
      x-mcp-tool: list_minifigures
      summary: 'Figures by identity: owned in sets, loose, missing.'
      tags:
      - Minifigures
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_problem'
      - $ref: '#/components/parameters/Q_theme'
      - $ref: '#/components/parameters/Q_year'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Q_sort'
      - $ref: '#/components/parameters/Q_inventory'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfMinifigureRow'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_minifigures
      x-piece: M.11b
  /minifigures/{id}:
    get:
      operationId: get_minifigures_by_id
      summary: 'One figure: sets, loose lines, missing, matches, prices.'
      description: The item detail of a minifigure by its Brick Work id (`used_in` the sets, `stock` the loose lines, `gaps` and `matches`). A merged id is `307` to the survivor's `/minifigures/{id}`; an item that is not a figure is `404`.
      tags:
      - Minifigures
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItemDetail'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_minifigures_by_no
      x-piece: M.11b
  /gaps:
    get:
      operationId: get_gaps
      x-mcp-tool: list_gaps
      summary: Missing items over all copies and loose figures.
      tags:
      - Matching
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_number'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_copy_id'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfGap'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_gaps
      x-piece: M.11b
  /matches:
    get:
      operationId: get_matches
      x-mcp-tool: list_matches
      summary: 'Suggestions: loose stock that fills a gap.'
      tags:
      - Matching
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_number'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_copy_id'
      - $ref: '#/components/parameters/Q_completes'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfMatch'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_matches
      x-piece: M.11b
  /instruction-files:
    get:
      operationId: get_instruction_files
      x-mcp-tool: list_instruction_files
      summary: Booklet files and booklet identities with coverage.
      tags:
      - Instructions
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_number'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_has_file'
      - $ref: '#/components/parameters/Q_archived'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfInstructionFile'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_instruction_files
      x-piece: M.11b
    post:
      operationId: post_instruction_files
      summary: Attach a PDF (multipart, up to 20 MB) to an item.
      tags:
      - Instructions
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/InstructionUpload'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenInstructionFile'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_instruction_files
      x-piece: M.11c
  /instruction-files/{id}:
    get:
      operationId: get_instruction_files_by_id
      summary: One file record.
      tags:
      - Instructions
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneInstructionFile'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_instruction_files_by_id
      x-piece: M.11b
    patch:
      operationId: patch_instruction_files_by_id
      summary: Rename the label.
      tags:
      - Instructions
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InstructionPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenInstructionFile'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_instruction_files_by_id
      x-piece: M.11c
    delete:
      operationId: delete_instruction_files_by_id
      summary: Archive a PDF association.
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Archived.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenDeleted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_instruction_files_by_id
      x-piece: M.11c
  /instruction-files/{id}/content:
    get:
      operationId: get_instruction_files_by_id_content
      summary: Download the PDF.
      tags:
      - Instructions
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      responses:
        '200':
          description: File.
          content:
            application/pdf:
              schema:
                type: string
                format: binary
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_instruction_files_by_id_content
      x-piece: M.11b
  /prices:
    get:
      operationId: get_prices
      summary: Current price per item, colour, condition and guide.
      tags:
      - Prices
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_number'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_condition'
      - $ref: '#/components/parameters/Q_guide'
      - $ref: '#/components/parameters/Q_source'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfPriceCurrent'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_prices
      x-piece: M.11b
  /items/{id}/prices:
    get:
      operationId: get_items_by_id_prices
      x-mcp-tool: get_prices
      summary: Current prices and recorded observations of one item.
      tags:
      - Prices
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_provider'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItemPrices'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items_by_type_by_no_prices
      x-piece: M.11b
    post:
      operationId: post_items_by_id_prices
      x-mcp-tool: record_price
      summary: Record one manual or valuation observation; Undo sets error=undone and recomputes price_current.
      tags:
      - Prices
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PriceCreate'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenPriceObservation'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_items_by_type_by_no_prices
      x-piece: M.11c
  /items/{id}/prices/history:
    get:
      operationId: get_items_by_id_prices_history
      summary: Observation history of one item.
      tags:
      - Prices
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_condition'
      - $ref: '#/components/parameters/DirectionNewest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfPriceObservation'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_items_by_type_by_no_prices_history
      x-piece: M.11b
  /prices/observations:
    post:
      operationId: post_prices_observations
      summary: Record up to 500 observations in one transaction.
      tags:
      - Prices
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PriceBatch'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenBulkResult'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_prices_observations
      x-piece: M.11c
  /items/{id}/prices/refresh:
    post:
      operationId: post_items_by_id_prices_refresh
      x-mcp-tool: refresh_price
      summary: Queue a market price refresh for one item.
      tags:
      - Prices
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshRequest'
      responses:
        '202':
          description: Accepted. The job runs in the background; poll GET /jobs/{id}.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJob'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_items_by_type_by_no_prices_refresh
      x-piece: M.11d
  /prices/stale:
    get:
      operationId: get_prices_stale
      x-mcp-tool: list_stale_prices
      summary: Items whose price is older than the freshness rule.
      tags:
      - Prices
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfStaleItem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_prices_stale
      x-piece: M.11b
  /prices/refresh:
    post:
      operationId: post_prices_refresh
      summary: Queue refresh jobs for every stale item.
      tags:
      - Prices
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJobList'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_prices_refresh
      x-piece: M.11d
  /wishes:
    get:
      operationId: get_wishes
      x-mcp-tool: list_wishes
      summary: Wishlist rows; under_max filters to rows priced under the wish maximum.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - read
      parameters:
      - name: list
        in: query
        schema:
          type: string
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Q_number'
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      - $ref: '#/components/parameters/Q_condition'
      - $ref: '#/components/parameters/Q_flag'
      - $ref: '#/components/parameters/Q_under_max'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Q_sort'
      - $ref: '#/components/parameters/Q_archived'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfWish'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_wishes
      x-piece: M.11b
    post:
      operationId: post_wishes
      x-mcp-tool: add_wish
      summary: Add a wish (same colour and item adds to the live row on decision=another).
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WishCreate'
      responses:
        '200':
          description: Skipped. The client asked for decision=skip and the item is already owned or wished; nothing was written, event_id is null.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSkipped'
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCreated'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_wishes
      x-piece: M.11c
  /wishes/{id}:
    get:
      operationId: get_wishes_by_id
      summary: One wish.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_wish_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneWish'
          headers:
            ETag:
              schema:
                type: string
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_wishes_by_id
      x-piece: M.11b
    patch:
      operationId: patch_wishes_by_id
      x-mcp-tool: update_wish
      summary: Edit quantity, colour, condition, max price, max price with box and their currencies, note.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_wish_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      - $ref: '#/components/parameters/IfMatch'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WishPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWish'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_wishes_by_id
      x-piece: M.11c
    delete:
      operationId: delete_wishes_by_id
      x-mcp-tool: archive_wish
      summary: Archive the wish.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_wish_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      - $ref: '#/components/parameters/IfMatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWish'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_wishes_by_id
      x-piece: M.11c
  /wishes/{id}/restore:
    post:
      operationId: post_wishes_by_id_restore
      summary: Restore an archived wish.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_wish_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWish'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_wishes_by_id_restore
      x-piece: M.11c
  /wishes/{id}/flags:
    put:
      operationId: put_wishes_by_id_flags
      summary: Replace the wish flags.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_wish_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlagSet'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenWish'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_wishes_by_id_flags
      x-piece: M.11c
  /wishes/{id}/to-owned:
    post:
      operationId: post_wishes_by_id_to_owned
      x-mcp-tool: wish_to_owned
      summary: Turn a wish into owned copies and archive the wish, one transaction.
      tags:
      - Wishlist
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_wish_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WishToOwned'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCreated'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_wishes_by_id_to_owned
      x-piece: M.11c
  /storages:
    get:
      operationId: get_storages
      x-mcp-tool: list_storages
      summary: Active storages with counts, plus the virtual "Not stored".
      tags:
      - Storages
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfStorage'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_storages
      x-piece: M.11b
    post:
      operationId: post_storages
      x-mcp-tool: create_storage
      summary: Create a storage.
      tags:
      - Storages
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StorageInput'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStorage'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_storages
      x-piece: M.11c
  /storages/{id}:
    get:
      operationId: get_storages_by_id
      summary: Storage with its contents.
      tags:
      - Storages
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneStorageDetail'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_storages_by_id
      x-piece: M.11b
    patch:
      operationId: patch_storages_by_id
      summary: Rename.
      tags:
      - Storages
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StorageInput'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStorage'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_storages_by_id
      x-piece: M.11c
    delete:
      operationId: delete_storages_by_id
      summary: Archive; refuses non-empty unless move_to_unstored=true.
      tags:
      - Storages
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Q_move_to_unstored'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStorage'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_storages_by_id
      x-piece: M.11c
  /storages/{id}/contents:
    post:
      operationId: post_storages_by_id_contents
      x-mcp-tool: move_to_storage
      summary: Move copies, stock and lots into this storage (id "unstored" for none). A lot carries its parts in the same storage.
      tags:
      - Storages
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StorageMove'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_storages_by_id_contents
      x-piece: M.11c
  /lots:
    get:
      operationId: get_lots
      x-mcp-tool: list_lots
      summary: Part lots.
      tags:
      - Lots
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_storage'
      - $ref: '#/components/parameters/Q_archived'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfLot'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_lots
      x-piece: M.11b
    post:
      operationId: post_lots
      summary: Create a lot from existing stock lines.
      tags:
      - Lots
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LotCreate'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenLot'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_lots
      x-piece: M.11c
  /lots/{id}:
    get:
      operationId: get_lots_by_id
      summary: Lot with its stock.
      tags:
      - Lots
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneLotDetail'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_lots_by_id
      x-piece: M.11b
    patch:
      operationId: patch_lots_by_id
      summary: Edit name, note, storage, purchase fields.
      tags:
      - Lots
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LotPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenLot'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_lots_by_id
      x-piece: M.11c
    delete:
      operationId: delete_lots_by_id
      summary: Archive the lot.
      tags:
      - Lots
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenLot'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_lots_by_id
      x-piece: M.11c
  /places:
    get:
      operationId: get_places
      x-mcp-tool: list_places
      summary: Purchase locations with counts and totals per currency.
      tags:
      - Places
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfPlace'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_places
      x-piece: M.11b
    post:
      operationId: post_places
      summary: Create a purchase location.
      tags:
      - Places
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NameInput'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenPlace'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_places
      x-piece: M.11c
  /places/{id}:
    patch:
      operationId: patch_places_by_id
      summary: Rename.
      tags:
      - Places
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NameInput'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenPlace'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_places_by_id
      x-piece: M.11c
    delete:
      operationId: delete_places_by_id
      summary: Archive retaining references; Undo restores the place.
      tags:
      - Places
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenDeleted'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_places_by_id
      x-piece: M.11c
  /flags:
    get:
      operationId: get_flags
      x-mcp-tool: list_flags
      summary: Flags of kind owner, status and tag.
      tags:
      - Flags
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_kind'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfFlag'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_flags
      x-piece: M.11b
    post:
      operationId: post_flags
      summary: Create a flag.
      tags:
      - Flags
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FlagInput'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenFlag'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_flags
      x-piece: M.11c
  /flags/{id}:
    patch:
      operationId: patch_flags_by_id
      summary: Rename.
      tags:
      - Flags
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NameInput'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenFlag'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_flags_by_id
      x-piece: M.11c
    delete:
      operationId: delete_flags_by_id
      summary: Archive retaining flag links; Undo restores the flag.
      tags:
      - Flags
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenDeleted'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_flags_by_id
      x-piece: M.11c
  /planning/ranking:
    get:
      operationId: get_planning_ranking
      x-mcp-tool: get_planning_ranking
      summary: Owned copies ranked by cost to complete, with the repair settings used.
      tags:
      - Planning
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_sort'
      - $ref: '#/components/parameters/Q_q'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RankingPage'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_planning_ranking
      x-piece: M.11b
  /planning/set-scores:
    get:
      operationId: get_planning_set_scores
      x-mcp-tool: get_planning_set_scores
      summary: The catalogue's sets ranked by how much of a pile of loose parts each explains.
      description: 'Scores the live loose stock of one lot, one storage (and the storages inside it), all loose stock, or a saved selection of stock lines
        (`stock`, repeated) against the active catalogue build; give exactly one of `lot`, `storage`, `loose=true` or `stock`. Read-only. Each set carries
        the evidence (the sum, over the lines of the pile that the set holds, of the line''s rarity weight ln(N/df) times the covered share of the set''s
        quantity), the coverage (evidence over the set''s own total weight), the covered and complete lines, the distinctive lines found of the set''s
        distinctive ones, the matched lines (the heaviest `detail` of them, with the stock flags passed through and summed per flag), and the swaps: the same
        part in another colour or as an alternate mould, listed apart and never counted in any number. Ranked by evidence, then coverage, then set id.
        ADR 0026.'
      tags:
      - Planning
      security:
      - bearerAuth:
        - read
      parameters:
      - name: lot
        in: query
        description: A lot id; scores its live loose parts and figures.
        schema:
          type: string
      - name: storage
        in: query
        description: A storage id; scores the live loose stock kept in it and in the storages inside it.
        schema:
          type: string
      - name: loose
        in: query
        description: true scores all live loose parts and figures.
        schema:
          type: boolean
      - name: stock
        in: query
        description: Stock line ids (live loose parts or figures), 1 to 5000 different ones.
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
          maxItems: 5000
          uniqueItems: true
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      - name: offset
        in: query
        schema:
          type: integer
          minimum: 0
          default: 0
      - name: detail
        in: query
        description: How many matched lines each set lists (the numbers always count all of them).
        schema:
          type: integer
          minimum: 0
          maximum: 50
          default: 10
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SetScorePage'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /lots/{id}/candidate-sets:
    get:
      operationId: get_lots_by_id_candidate_sets
      x-mcp-tool: get_lot_candidate_sets
      summary: The sets a lot may have come from, ranked, with reasons and distinctive parts (Lot Detective).
      description: 'Scores the live loose parts and figures of the lot against the active catalogue build (the engine of `GET /planning/set-scores`, ADR 0026)
        and returns the candidate sets. The `score` is 0 to 100: how strongly the found parts point to the set, weighed by how rare each part is, relative to the
        best candidate (the first set that passes the set filters scores 100). It is NOT a probability and says nothing about how likely the set is to be the
        right one in absolute terms. Each set has `reasons` (for example "7 of 9 distinctive parts found", "2 printed parts only in this set"), the distinctive
        parts found and not found yet (a distinctive part is held by at most 25 sets; up to 20 of each, heaviest first, with their pictures) and the stock
        flags passed to the engine (a flag named Sticker as `sticker`), and the swaps (the lot has the part in another colour, or an alternate mould),
        listed apart and never in the score. A Sticker flag raises the sets that hold the part and a sticker sheet, and a confirmed sticker is strong evidence for its
        set (`POST /lots/{id}/stock/{stock_id}/sticker`). By default `ignore_common` drops the lines held by more than N sets before scoring
        (setting `candidate_sets_common_max`, default 300). The theme filter takes a catalogue theme id or a name (its sub-themes are included); the part
        range is the catalogue''s part count of the set. Read-only; an unknown lot is 404.'
      tags:
      - Lots
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - name: min_score
        in: query
        description: Only sets scoring at least this (0 to 100).
        schema:
          type: number
          minimum: 0
          maximum: 100
          default: 0
      - name: theme
        in: query
        description: A catalogue theme id or name; the theme and the themes below it.
        schema:
          type: string
      - name: year_from
        in: query
        description: Only sets released in this year or later.
        schema:
          type: integer
          minimum: 0
      - name: year_to
        in: query
        description: Only sets released in this year or earlier.
        schema:
          type: integer
          minimum: 0
      - name: parts_min
        in: query
        description: Only sets with at least this many parts (the catalogue's part count).
        schema:
          type: integer
          minimum: 0
      - name: parts_max
        in: query
        description: Only sets with at most this many parts (the catalogue's part count).
        schema:
          type: integer
          minimum: 0
      - name: ignore_common
        in: query
        description: Drop the parts that more than `candidate_sets_common_max` sets hold before scoring (default true).
        schema:
          type: boolean
          default: true
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      - name: offset
        in: query
        schema:
          type: integer
          minimum: 0
          default: 0
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CandidateSetPage'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /planning/build-scout:
    get:
      operationId: get_planning_build_scout
      x-mcp-tool: get_planning_build_scout
      summary: 'Build Scout (#9): the catalogue''s sets ranked by how much of each the loose stock already makes.'
      description: 'For every catalogue set that shares a part with the chosen loose stock: the parts available (the sum over the set''s own part lines of
        min(have, need); spares and a minifigure''s components are not part lines), the percent of the set''s parts that is, the missing parts and lines, the
        whole figures available of those required (a loose whole figure counts), and with `detail` the biggest missing lines, the missing figures, the cost
        to complete (missing lines priced from the current prices, in the one currency most are priced in, with the number of unpriced lines) and the swaps
        (another colour, an alternate mould), listed apart and never in a number. Ranked by percent available, then fewest missing parts, then set id. The stock
        is the live loose parts and whole figures with what can be given (damaged rows give nothing unless `damaged=true`) of the chosen sources: `loose=true`
        (the stock kept in no lot or storage), the `lot` and `storage` ids (a storage with the storages inside it), or all loose stock when none is given.
        Read-only. ADR 0027.'
      tags:
      - Planning
      security:
      - bearerAuth:
        - read
      parameters:
      - name: lot
        in: query
        description: Lot ids (repeated); the stock kept in them.
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
          maxItems: 500
          uniqueItems: true
      - name: storage
        in: query
        description: Storage ids (repeated); the stock kept in them and in the storages inside them.
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
          maxItems: 500
          uniqueItems: true
      - name: loose
        in: query
        description: true adds the stock kept in no lot or storage.
        schema:
          type: boolean
      - name: damaged
        in: query
        description: true counts stock whose condition is damaged (off by default).
        schema:
          type: boolean
      - name: min_percent
        in: query
        description: The least percent of a set's parts that must be available.
        schema:
          type: integer
          minimum: 0
          maximum: 100
          default: 60
      - name: max_missing
        in: query
        description: The most missing parts (pieces) a set may have.
        schema:
          type: integer
          minimum: 0
      - name: theme
        in: query
        description: A catalogue theme id or name (any case), with its sub-themes.
        schema:
          type: string
      - name: year_from
        in: query
        schema:
          type: integer
      - name: year_to
        in: query
        schema:
          type: integer
      - name: size_from
        in: query
        description: The fewest parts a set has (spares left out).
        schema:
          type: integer
          minimum: 0
      - name: size_to
        in: query
        schema:
          type: integer
          minimum: 0
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      - name: offset
        in: query
        schema:
          type: integer
          minimum: 0
          default: 0
      - name: detail
        in: query
        description: How many missing lines each set lists, with its missing figures, cost and swaps (0 lists none of them).
        schema:
          type: integer
          minimum: 0
          maximum: 50
          default: 0
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BuildScoutPage'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /lots/{id}/stock/{stock_id}/stickers:
    get:
      operationId: get_lots_by_id_stock_by_stock_id_stickers
      x-mcp-tool: list_sticker_candidates
      summary: The sets a sticker on a part line of a lot may belong to (sets that hold the part in its colour and a sticker sheet).
      description: 'The catalogue does not say which part a sticker goes on, so this is the fallback: the live catalogue sets whose latest inventory holds the
        part in the line''s colour AND a sticker sheet (a part of the category named `Stickers`; spare lines are left out). A set with several sheets is one row,
        its sheet with the lowest number first; sets with a sheet picture come first, then the earlier year. `sticker` says whether the line holds the Sticker flag
        and which set was confirmed ("This one"). Read-only; a line that is not a live part of the lot is 404.'
      tags:
      - Lots
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_stock_id'
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
      - name: offset
        in: query
        schema:
          type: integer
          minimum: 0
          default: 0
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StickerCandidatePage'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /lots/{id}/stock/{stock_id}/sticker:
    post:
      operationId: post_lots_by_id_stock_by_stock_id_sticker
      x-mcp-tool: confirm_sticker
      summary: 'Confirm the sticker of a part line: the sheet of a set from the candidates ("This one"). One undoable event; choosing what is already chosen writes nothing.'
      description: 'The line must hold the Sticker flag (409 otherwise) and the pair must be one of the line''s candidates (422 otherwise). A confirmed sticker is
        strong evidence for its set in Lot Detective and `GET /planning/set-scores`; the flag alone is a smaller hint. Undo takes the choice back.'
      tags:
      - Lots
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_stock_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StickerConfirm'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSticker'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
    delete:
      operationId: delete_lots_by_id_stock_by_stock_id_sticker
      x-mcp-tool: clear_sticker
      summary: 'Not a sticker: remove the Sticker flag from a part line and stop counting a confirmed sticker. One undoable event; a line without the flag writes nothing.'
      tags:
      - Lots
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_stock_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSticker'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /lots/{id}/pull-list/{set_id}:
    get:
      operationId: get_lots_by_id_pull_list_by_set_id
      x-mcp-tool: get_lot_pull_list
      summary: 'The pull list of a set for a lot (#202, Lot Detective): the set''s lines with what each needs, what the lot holds and what is found so far.'
      description: 'The set''s own parts (the latest Rebrickable list, sub-sets expanded, spares left out) and its whole minifigures, as Build Scout reads them.
        Per line: `need` (what the set has), `held` (what the lot can give: damaged rows give nothing), `found` (`held` plus the pieces ticked in the bulk
        and not filed yet, never above `need`) and `to_find`. `totals` count pieces over all lines: `moves` is what Make it a copy would move out of the lot,
        `missing` what it would record as missing on the copy and `stays` what the lot keeps. Lines come in category then number order (whole figures last);
        `show` keeps the lines still to find (`find`), the complete ones (`found`) or all. `refusal` says why Make it a copy would be refused (a set made of
        other sets, nothing found yet). Read-only; an unknown lot or set is 404, a set with no part list 422.'
      tags:
      - Lots
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_set_item_id'
      - name: show
        in: query
        description: Which lines to list; the totals always count the whole list.
        schema:
          type: string
          enum:
          - find
          - found
          - all
          default: all
      - name: limit
        in: query
        schema:
          type: integer
          minimum: 1
          maximum: 500
          default: 100
      - name: offset
        in: query
        schema:
          type: integer
          minimum: 0
          default: 0
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PullListPage'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /lots/{id}/pull-list/{set_id}/found:
    post:
      operationId: post_lots_by_id_pull_list_by_set_id_found
      summary: 'Save how many of one part of the pull list are found (an absolute count, idempotent; kept between visits). Not an event: nothing to undo.'
      description: 'The count includes what the lot already holds of the line (`held`); a count below it only drops the pieces ticked in the bulk. Pieces ticked
        and not in the lot yet are filed in the lot, as found in the bulk, when Make it a copy runs. The line must be on the list (422 otherwise) and `found`
        is 0 to its `need`. `event_id` and `undo_url` are always null.'
      tags:
      - Lots
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_set_item_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PullFound'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenPullFound'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /lots/{id}/pull-list/{set_id}/make-copy:
    post:
      operationId: post_lots_by_id_pull_list_by_set_id_make_copy
      x-mcp-tool: make_copy_from_lot
      summary: 'Make it a copy (#202): the found pieces of the pull list move out of the lot into a new copy of the set, the rest recorded as missing on it. One undoable event.'
      description: 'One transaction and one event (`copy` / `make_from_stock`). The pieces ticked in the bulk are filed in the lot first, then exactly the found
        counts move from the lot''s stock rows into the copy (nothing of another lot); everything the set has and was not found is recorded as missing on the
        copy, which starts used, incomplete and not checked. The lot keeps the leftovers and the progress of this (lot, set) is cleared. Undo
        (`POST /events/{id}/undo`) puts the stock back and archives the copy; the pieces ticked in the bulk stay filed in the lot. Refused with 422 and nothing
        written: a set made of other sets, nothing found yet, a set with no part list.'
      tags:
      - Lots
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/Path_set_item_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopyFromLot'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /export/missing.csv:
    get:
      operationId: get_export_missing_csv
      summary: 'Missing parts of the chosen copies as CSV (the printable list, #43).'
      security:
      - bearerAuth:
        - read
      parameters:
      - name: copy_id
        in: query
        description: Repeated copy IDs.
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
          maxItems: 2000
          uniqueItems: true
      - name: ids
        in: query
        description: Comma-separated copy IDs; alternative to copy_id.
        schema:
          type: string
      responses:
        '200':
          description: CSV with the columns Item type, Item number, Name, Colour, Colour id, Condition, Quantity.
          content:
            text/csv:
              schema:
                type: string
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_export_missing_csv
      x-piece: M.11b
  /export/picker.csv:
    get:
      operationId: get_export_picker_csv
      summary: Part Runner results for the chosen copies as CSV, in pick order (#43).
      security:
      - bearerAuth:
        - read
      parameters:
      - name: copy_id
        in: query
        description: Repeated copy IDs.
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
          maxItems: 2000
          uniqueItems: true
      - name: rank
        in: query
        description: Pick order keys (category, colour, size, set, storage); default all.
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
      responses:
        '200':
          description: CSV with the columns Rank, Item type, Item number, Name, Colour, Colour id, Quantity, Sets, Storage.
          content:
            text/csv:
              schema:
                type: string
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_export_picker_csv
      x-piece: M.11b
  /export/wishlist.csv:
    get:
      operationId: get_export_wishlist_csv
      summary: The wishlist (one list or all) as CSV (#43).
      security:
      - bearerAuth:
        - read
      parameters:
      - name: list
        in: query
        description: A wishlist id, or all (default).
        schema:
          type: string
      responses:
        '200':
          description: CSV with the columns List, Item type, Item number, Name, Colour, Colour id, Quantity, Condition, Max price, Currency, Note.
          content:
            text/csv:
              schema:
                type: string
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_export_wishlist_csv
      x-piece: M.11b
  /export/missing.json:
    get:
      operationId: get_export_missing_json
      summary: Aggregated missing items for chosen copies, using the XML export rules.
      description: One line per item, colour and condition, each with the BrickLink type, number and colour number the XML names it by. A line with no confirmed BrickLink number is not in the XML; it is in `skipped` with the reason.
      security:
      - bearerAuth:
        - read
      parameters:
      - name: ids
        in: query
        description: Comma-separated copy IDs (1 to 2000 unique IDs).
        schema:
          type: string
      - name: copy_id
        in: query
        description: Repeated copy IDs; alternative to comma-separated ids.
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
          maxItems: 2000
          uniqueItems: true
      responses:
        '200':
          description: Missing items.
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      required:
                      - item
                      - color
                      - quantity
                      - condition
                      - bricklink
                      properties:
                        item:
                          $ref: '#/components/schemas/Item'
                        color:
                          oneOf:
                          - $ref: '#/components/schemas/Color'
                          - type: 'null'
                        quantity:
                          type: integer
                        condition:
                          enum:
                          - new
                          - used
                          - null
                        bricklink:
                          description: The BrickLink type, item number and colour number of the wanted-list line.
                          type: object
                          required:
                          - type
                          - 'no'
                          - color_id
                          properties:
                            type:
                              type: string
                            'no':
                              type: string
                            color_id:
                              type:
                              - integer
                              - 'null'
                  skipped:
                    description: Lines the XML leaves out because BrickLink cannot name them.
                    type: array
                    items:
                      type: object
                      required:
                      - item
                      - color
                      - quantity
                      - condition
                      - why
                      properties:
                        item:
                          $ref: '#/components/schemas/Item'
                        color:
                          oneOf:
                          - $ref: '#/components/schemas/Color'
                          - type: 'null'
                        quantity:
                          type: integer
                        condition:
                          enum:
                          - new
                          - used
                          - null
                        why:
                          type: string
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_export_missing_json
      x-piece: M.11b
  /export/missing.xml:
    get:
      operationId: get_export_missing_xml
      summary: BrickLink wanted-list XML of missing items for chosen copies.
      tags:
      - Planning
      security:
      - bearerAuth:
        - read
      parameters:
      - name: copy_id
        in: query
        description: Repeated copy IDs, or use comma-separated ids (1 to 2000 unique IDs).
        style: form
        explode: true
        schema:
          type: array
          items:
            type: string
          maxItems: 2000
          uniqueItems: true
      - name: ids
        in: query
        description: Comma-separated copy IDs; alternative to repeated copy_id.
        schema:
          type: string
      responses:
        '200':
          description: File.
          content:
            application/xml:
              schema:
                type: string
                format: binary
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_export_missing_xml
      x-piece: M.11b
  /orders:
    get:
      operationId: get_orders
      x-mcp-tool: list_orders
      summary: Orders with line and receipt state.
      tags:
      - Orders
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_bricklink_order_id'
      - $ref: '#/components/parameters/Q_status'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfOrder'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_orders
      x-piece: M.11d
  /orders/export.csv:
    get:
      operationId: get_orders_export_csv
      summary: Saved order lines (kind=lines) or one row per order with new and used totals (kind=summary) as CSV, filtered by order date and store (#44).
        Totals never mix currencies.
      security:
      - bearerAuth:
        - read
      parameters:
      - name: from
        in: query
        schema:
          type: string
          format: date
      - name: to
        in: query
        schema:
          type: string
          format: date
      - name: store
        in: query
        schema:
          type: string
      - name: kind
        in: query
        schema:
          type: string
          enum:
          - lines
          - summary
          default: lines
      responses:
        '200':
          description: 'CSV. Lines: Order, Date, Store, Seller, Item type, Item number, Name, Colour, Colour id, Condition, Quantity, Unit price, Line total,
            Currency. Summary: Order, Date, Store, Seller, Status, Lines, Items, New total, Used total, Other costs, Grand total, Currency.'
          content:
            text/csv:
              schema:
                type: string
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_orders_export_csv
      x-piece: M.11d
  /orders/{id}:
    get:
      operationId: get_orders_by_id
      x-mcp-tool: get_order
      summary: Order with documents and lines.
      tags:
      - Orders
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneOrderDetail'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_orders_by_id
      x-piece: M.11d
  /orders/documents:
    post:
      operationId: post_orders_documents
      x-mcp-tool: import_order
      summary: 'Import an order document: pasted email, BrickLink XML, or fetch by order number with the user key.'
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderImport'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenOrderImportResult'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_orders_documents
      x-piece: M.11d
  /orders/{id}/lines/{line_id}:
    patch:
      operationId: patch_orders_by_id_lines_by_line_id
      summary: Match a line to a catalogue identity.
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/Path_line_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderLineMatch'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_orders_by_id_lines_by_line_id
      x-piece: M.11d
  /orders/{id}/lines/{line_id}/hold:
    put:
      operationId: put_orders_by_id_lines_by_line_id_hold
      summary: Hold or release a line.
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/Path_line_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Hold'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_orders_by_id_lines_by_line_id_hold
      x-piece: M.11d
  /orders/{id}/documents/{doc_id}/phase:
    post:
      operationId: post_orders_by_id_documents_by_doc_id_phase
      summary: 'Move a document: review, reopen or save.'
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/Path_doc_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderPhase'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_orders_by_id_documents_by_doc_id_phase
      x-piece: M.11d
  /orders/{id}/received:
    post:
      operationId: post_orders_by_id_received
      summary: Record received counts per line.
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderReceived'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_orders_by_id_received
      x-piece: M.11d
  /orders/{id}/allocate:
    post:
      operationId: post_orders_by_id_allocate
      summary: Allocate received lines to copies or stock.
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderAllocate'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_orders_by_id_allocate
      x-piece: M.11d
  /orders/{id}/reconcile:
    post:
      operationId: post_orders_by_id_reconcile
      summary: Reconcile the order.
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_orders_by_id_reconcile
      x-piece: M.11d
  /orders/{id}/short.xml:
    get:
      operationId: get_orders_by_id_short_xml
      summary: BrickLink XML of the still-missing lines.
      tags:
      - Orders
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      responses:
        '200':
          description: File.
          content:
            application/xml:
              schema:
                type: string
                format: binary
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_orders_by_id_short_xml
      x-piece: M.11d
  /orders/{id}/allocations/retry:
    post:
      operationId: post_orders_by_id_allocations_retry
      summary: Retry reviewed allocation choices atomically against current counts and gaps.
      tags:
      - Orders
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrderAllocate'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenReceipt'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_orders_by_id_allocations_retry
      x-piece: M.11d
  /orders/{id}/allocation-review:
    get:
      operationId: get_orders_by_id_allocation_review
      summary: Read order allocation-review.
      tags:
      - Orders
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfOrderReview'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_orders_by_id_allocation_review
      x-piece: M.11d
  /orders/{id}/allocations:
    get:
      operationId: get_orders_by_id_allocations
      summary: Read order allocations.
      tags:
      - Orders
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfAllocation'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_orders_by_id_allocations
      x-piece: M.11d
  /orders/{id}/history:
    get:
      operationId: get_orders_by_id_history
      summary: Read order history.
      tags:
      - Orders
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfOrderHistory'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_orders_by_id_history
      x-piece: M.11d
  /events:
    get:
      operationId: get_events
      x-mcp-tool: list_events
      summary: Audit events, newest first.
      tags:
      - Events
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_entity'
      - $ref: '#/components/parameters/Q_field'
      - $ref: '#/components/parameters/Q_via'
      - $ref: '#/components/parameters/Q_since'
      - $ref: '#/components/parameters/Q_undoable'
      - $ref: '#/components/parameters/DirectionNewest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfEvent'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_events
      x-piece: M.11b
  /events/{id}:
    get:
      operationId: get_events_by_id
      summary: One event with old and new values.
      tags:
      - Events
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneEvent'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_events_by_id
      x-piece: M.11b
  /events/{id}/undo:
    post:
      operationId: post_events_by_id_undo
      x-mcp-tool: undo_event
      summary: Undo M3 collection or supported standalone core receipts. Token, source key and source toggle receipts (alone or inside an API event) require
        admin; other receipts require write.
      tags:
      - Events
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenUndoResult'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '503':
          $ref: '#/components/responses/Problem'
        '403':
          $ref: '#/components/responses/Forbidden'
        '400':
          $ref: '#/components/responses/Problem'
        '428':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_events_by_id_undo
      x-piece: M.11c
  /jobs:
    get:
      operationId: get_jobs
      x-mcp-tool: list_jobs
      summary: Import and refresh jobs with steps.
      tags:
      - Jobs
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Q_state'
      - $ref: '#/components/parameters/Q_failed'
      - $ref: '#/components/parameters/DirectionNewest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfJob'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_jobs
      x-piece: M.11d
  /jobs/{id}:
    get:
      operationId: get_jobs_by_id
      summary: One job.
      tags:
      - Jobs
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneJob'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_jobs_by_id
      x-piece: M.11d
  /jobs/{id}/retry:
    post:
      operationId: post_jobs_by_id_retry
      x-mcp-tool: retry_job
      summary: Retry failed steps (all, or one step). Queues the work and returns the job.
      tags:
      - Jobs
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobRetry'
      responses:
        '202':
          description: Accepted. The job runs in the background; poll GET /jobs/{id}.
          headers:
            Location:
              description: Poll this job.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJob'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_jobs_by_id_retry
      x-piece: M.11d
  /jobs/{id}/resume:
    post:
      operationId: post_jobs_by_id_resume
      summary: Resume an interrupted or budget-waiting job.
      tags:
      - Jobs
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted. The job runs in the background; poll GET /jobs/{id}.
          headers:
            Location:
              description: Poll this job.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJob'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_jobs_by_id_resume
      x-piece: M.11d
  /jobs/drain:
    post:
      operationId: post_jobs_drain
      summary: Run one drain of due jobs in the request.
      tags:
      - Jobs
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJobList'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_jobs_drain
      x-piece: M.11d
  /jobs/instruction-identities:
    post:
      operationId: post_jobs_instruction_identities
      summary: Queue identity refresh for booklets without a file.
      tags:
      - Jobs
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '202':
          description: Accepted. The jobs run in the background; poll GET /jobs/{id}.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJobList'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_jobs_instruction_identities
      x-piece: M.11d
  /jobs/pictures:
    post:
      operationId: post_jobs_pictures
      summary: Queue a picture refresh for a scope.
      tags:
      - Jobs
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PictureRefresh'
      responses:
        '202':
          description: Accepted. The job runs in the background; poll GET /jobs/{id}.
          headers:
            Location:
              description: Poll this job.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenJobList'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_jobs_pictures
      x-piece: M.11d
  /sources:
    get:
      operationId: get_sources
      x-mcp-tool: get_sources
      summary: Sources with key state (configured yes or no), budget, usage today, last success and error.
      tags:
      - Sources
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfSource'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_sources
      x-piece: M.11d
  /sources/{source}:
    patch:
      operationId: patch_sources_by_source
      summary: Enable or disable a source. Undo restores the previous state.
      tags:
      - Sources
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/Path_source'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SourceToggle'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSource'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_sources_by_source
      x-piece: M.11d
  /catalogue/import:
    post:
      operationId: post_catalogue_import
      summary: Rebuild the catalogue file from the BrickLink XML files beside the database. No path or URL parameter; not undoable.
      tags:
      - Sources
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Done.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCatalogueStatus'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_catalogue_import
      x-piece: M.11d
  /sync/{source}:
    get:
      operationId: get_sync_by_source
      x-mcp-tool: get_sync_status
      summary: 'Sync status per source: credentials (never their values), link, last pull, last send and what is waiting.'
      tags:
      - Sync
      security:
      - bearerAuth:
        - read
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneSyncStatus'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_sync_by_source
      x-piece: M.11d
  /sync/{source}/lists:
    get:
      operationId: get_sync_by_source_lists
      summary: The site's set lists (Rebrickable); Brickset has none. One remote call.
      tags:
      - Sync
      security:
      - bearerAuth:
        - read
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SyncListPage'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_sync_by_source_lists
      x-piece: M.11d
  /sync/{source}/link:
    put:
      operationId: put_sync_by_source_link
      summary: 'Choose the remote lists: Rebrickable owned (ids), wishlist (id), send_to (id); both: wish_list (a Brick Work wishlist).'
      tags:
      - Sync
      security:
      - bearerAuth:
        - write
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                owned:
                  type: array
                  items:
                    type: integer
                wishlist:
                  type:
                  - integer
                  - 'null'
                send_to:
                  type:
                  - integer
                  - 'null'
                wish_list:
                  type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncStatus'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_sync_by_source_link
      x-piece: M.11d
  /sync/{source}/pull/plan:
    post:
      operationId: post_sync_by_source_pull_plan
      x-mcp-tool: plan_sync_pull
      summary: 'Fetch the remote collection and compare: add here, only here, differs, conflict (changed in both places), unmatched. Writes nothing to the
        collection; the plan expires after 24 hours.'
      tags:
      - Sync
      security:
      - bearerAuth:
        - write
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Plan created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncPlan'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_sync_by_source_pull_plan
      x-piece: M.11d
  /sync/{source}/pull/apply:
    post:
      operationId: post_sync_by_source_pull_apply
      x-mcp-tool: apply_sync_pull
      summary: 'Apply a pull plan: one copy per missing unit (flag imported from <site>, condition and completeness unset) and missing wishes, in one transaction.
        Ticked defaults to the suggested rows; conflicts only when ticked. Undo with POST /events/{id}/undo.'
      tags:
      - Sync
      security:
      - bearerAuth:
        - write
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
              - plan_id
              properties:
                plan_id:
                  type: string
                ticked:
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncApplied'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_sync_by_source_pull_apply
      x-piece: M.11d
  /sync/{source}/send/plan:
    post:
      operationId: post_sync_by_source_send_plan
      x-mcp-tool: plan_sync_send
      summary: 'The remote calls a send would make: set counts and wishes; removals are never ticked by default.'
      tags:
      - Sync
      security:
      - bearerAuth:
        - write
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Plan created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncPlan'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_sync_by_source_send_plan
      x-piece: M.11d
  /sync/{source}/send/apply:
    post:
      operationId: post_sync_by_source_send_apply
      summary: Perform the ticked remote calls; each row reports sent, unchanged, failed, paused (budget) or key_rejected. Remote changes are not undone
        by Brick Work's Undo; re-applying retries only rows not yet sent.
      tags:
      - Sync
      security:
      - bearerAuth:
        - admin
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
              - plan_id
              properties:
                plan_id:
                  type: string
                ticked:
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncSent'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_sync_by_source_send_apply
      x-piece: M.11d
  /sources/{source}/user:
    put:
      operationId: put_sources_by_source_user
      summary: Store a user token (Rebrickable) or userHash (Brickset) you generated on the site. Write-only; BW_SECRET_KEY required.
      tags:
      - Sync
      security:
      - bearerAuth:
        - admin
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
              - value
              properties:
                value:
                  type: string
                  minLength: 8
                  maxLength: 256
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncCredentials'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_sources_source_user
      x-piece: M.11d
    delete:
      operationId: delete_sources_by_source_user
      summary: Archive the stored user token or hash; Undo restores it.
      tags:
      - Sync
      security:
      - bearerAuth:
        - admin
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncCredentials'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_sources_source_user
      x-piece: M.11d
  /sources/{source}/user/connect:
    post:
      operationId: post_sources_by_source_user_connect
      summary: 'One-time connect: the username and password go straight to the site (Rebrickable POST /users/_token/, Brickset login); only the returned
        token or hash is stored, encrypted. The password is never stored, logged or returned.'
      tags:
      - Sync
      security:
      - bearerAuth:
        - admin
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
              - username
              - password
              properties:
                username:
                  type: string
                password:
                  type: string
                  format: password
                  writeOnly: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSyncCredentials'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_sources_source_user_connect
      x-piece: M.11d
  /sources/{source}/user/test:
    post:
      operationId: post_sources_by_source_user_test
      summary: One remote call that proves the stored user token or hash works.
      tags:
      - Sync
      security:
      - bearerAuth:
        - admin
      parameters:
      - name: source
        in: path
        required: true
        schema:
          type: string
          enum:
          - rebrickable
          - brickset
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenKeyTest'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_sources_source_user_test
      x-piece: M.11d
  /sources/{source}/key:
    put:
      operationId: put_sources_by_source_key
      summary: Encrypt and store a source key (replaces a stored one). Write-only; BW_SECRET_KEY required.
      tags:
      - Sources
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/Path_source'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SourceKeyInput'
      responses:
        '200':
          description: Stored. The key value is never returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSource'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_sources_source_key
      x-piece: M.11d
    delete:
      operationId: delete_sources_by_source_key
      summary: Archive the stored key; the source stops using it and Undo restores it.
      tags:
      - Sources
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/Path_source'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Archived.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSource'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_sources_source_key
      x-piece: M.11d
  /sources/{source}/key/test:
    post:
      operationId: post_sources_by_source_key_test
      summary: Make one budgeted call with the key in use. The result carries no key material; not undoable.
      tags:
      - Sources
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/Path_source'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: The key works.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenKeyTest'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_sources_source_key_test
      x-piece: M.11d
  /exchange-rates:
    get:
      operationId: get_exchange_rates
      summary: Exchange rates per 1 EUR (hand-entered or ECB) and the display currency (#39). Stored amounts never change currency.
      security:
      - bearerAuth:
        - read
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                required:
                - data
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ExchangeRate'
                  display_currency:
                    type: string
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_exchange_rates
      x-piece: M.11d
  /exchange-rates/{code}:
    put:
      operationId: put_exchange_rates_by_code
      summary: Enter (or with null remove) one rate per 1 EUR by hand.
      security:
      - bearerAuth:
        - admin
      parameters:
      - name: code
        in: path
        required: true
        schema:
          type: string
          pattern: ^[A-Za-z]{3}$
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
              - per_eur
              properties:
                per_eur:
                  type:
                  - string
                  - number
                  - 'null'
      responses:
        '200':
          description: Saved; the full rate list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenExchangeRates'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: put_exchange_rates_by_code
      x-piece: M.11d
  /exchange-rates/ecb:
    post:
      operationId: post_exchange_rates_ecb
      summary: Load the ECB daily reference rates (one keyless request); hand-entered rates are kept.
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Loaded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenEcbResult'
        '502':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_exchange_rates_ecb
      x-piece: M.11d
  /settings:
    get:
      operationId: get_settings
      x-mcp-tool: get_settings
      summary: Allowed settings and freshness rules.
      tags:
      - Settings
      security:
      - bearerAuth:
        - read
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneSettings'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_settings
      x-piece: M.11c
    patch:
      operationId: patch_settings
      summary: Update allowed settings (whitelist).
      tags:
      - Settings
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SettingsPatch'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenSettings'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: patch_settings
      x-piece: M.11c
  /statistics:
    get:
      operationId: get_statistics
      x-mcp-tool: get_statistics
      summary: Counts by completeness, theme, storage, place.
      tags:
      - Admin
      security:
      - bearerAuth:
        - read
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneStatistics'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_statistics
      x-piece: M.11b
  /database/check:
    get:
      operationId: get_database_check
      summary: Integrity, foreign-key check and row counts.
      tags:
      - Admin
      security:
      - bearerAuth:
        - admin
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneDatabaseCheck'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_database_check
      x-piece: M.11d
  /database/export:
    get:
      operationId: get_database_export
      summary: SQLite snapshot download. Stored source keys, even encrypted, are removed from the copy; refuses (409) if known plaintext credentials would
        remain.
      tags:
      - Admin
      security:
      - bearerAuth:
        - admin
      responses:
        '200':
          description: File.
          content:
            application/vnd.sqlite3:
              schema:
                type: string
                format: binary
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_database_export
      x-piece: M.11d
  /imports/bricktracker:
    post:
      operationId: post_imports_bricktracker
      summary: Upload a BrickTracker app.db (any upstream version, up to 200 MB) and get an import plan. A copy is upgraded with upstream's migrations and
        compared with this collection; nothing is written to the collection.
      tags:
      - Admin
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              additionalProperties: false
              properties:
                file:
                  type: string
                  format: binary
              required:
              - file
      responses:
        '201':
          description: Plan created (expires after 24 hours).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenImportPlan'
        '413':
          $ref: '#/components/responses/Problem'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_imports_bricktracker
      x-piece: M.11d
  /imports/{id}/apply:
    post:
      operationId: post_imports_by_id_apply
      summary: 'Apply an import plan: rows marked add are written in one transaction; locked rows (already imported, duplicate wishes) are always skipped.
        Undo with POST /events/{id}/undo (admin).'
      tags:
      - Admin
      security:
      - bearerAuth:
        - admin
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                decisions:
                  type: object
                  additionalProperties:
                    type: string
                    enum:
                    - add
                    - skip
      responses:
        '200':
          description: Applied; the event id undoes the whole import.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenImportApplied'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_imports_by_id_apply
      x-piece: M.11d
  /identifications:
    post:
      operationId: post_identifications
      summary: Upload an image to Brickognize (image, up to 8 MB). Undo archives the record.
      tags:
      - Admin
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              additionalProperties: false
              properties:
                file:
                  type: string
                  format: binary
              required:
              - file
      responses:
        '201':
          description: Identified and recorded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenIdentification'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '424':
          $ref: '#/components/responses/DependencyFailed'
        '429':
          $ref: '#/components/responses/BudgetExhausted'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_identifications
      x-piece: M.11d
    get:
      operationId: get_identifications
      summary: Photo identification history; archived rows hidden.
      tags:
      - Admin
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfIdentification'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_identifications
      x-piece: M.11d
  /tokens:
    get:
      operationId: get_tokens
      summary: 'Tokens: name, scopes, created, last used, revoked. Never the secret.'
      tags:
      - Tokens
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      - $ref: '#/components/parameters/Direction'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfToken'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '503':
          $ref: '#/components/responses/Problem'
        '403':
          $ref: '#/components/responses/Forbidden'
        '400':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_tokens
      x-piece: M.11d
    post:
      operationId: post_tokens
      summary: Create a token. The secret is shown once in this response.
      tags:
      - Tokens
      security:
      - bearerAuth:
        - admin
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenCreate'
      responses:
        '201':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenTokenCreated'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '503':
          $ref: '#/components/responses/Problem'
        '403':
          $ref: '#/components/responses/Forbidden'
        '400':
          $ref: '#/components/responses/Problem'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_tokens
      x-piece: M.11d
  /tokens/{id}:
    delete:
      operationId: delete_tokens_by_id
      summary: Revoke a token.
      tags:
      - Tokens
      security:
      - bearerAuth:
        - admin
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: Written. One transaction, one events row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenToken'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '503':
          $ref: '#/components/responses/Problem'
        '403':
          $ref: '#/components/responses/Forbidden'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_tokens_by_id
      x-piece: M.11d
  /copies/{id}/photos:
    post:
      operationId: post_copies_by_id_photos
      summary: Upload an own photo (image, up to 15 MB). Undo archives it.
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              additionalProperties: false
              properties:
                file:
                  type: string
                  format: binary
                caption:
                  type: string
              required:
              - file
      responses:
        '200':
          description: OK; writes include event_id and undo_url.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_copies_id_photos
      x-piece: M.11c
  /stock/{id}/photos:
    post:
      operationId: post_stock_by_id_photos
      summary: Upload an own photo (image, up to 15 MB). Undo archives it.
      tags:
      - Loose stock
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              additionalProperties: false
              properties:
                file:
                  type: string
                  format: binary
                caption:
                  type: string
              required:
              - file
      responses:
        '200':
          description: OK; writes include event_id and undo_url.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStock'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_stock_id_photos
      x-piece: M.11c
  /identifications/{id}:
    delete:
      operationId: delete_identifications_by_id
      summary: Archive identification; Undo restores it.
      tags:
      - Admin
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Archived.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenIdentification'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: delete_identifications_id
      x-piece: M.11d
    get:
      operationId: get_identifications_by_id
      summary: Read identification result.
      tags:
      - Admin
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK; writes include event_id and undo_url.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneIdentification'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_identifications_id
      x-piece: M.11d
  /identifications/{id}/thumb:
    get:
      operationId: get_identifications_by_id_thumb
      summary: Download identification thumbnail.
      tags:
      - Admin
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_id'
      responses:
        '200':
          description: OK; writes include event_id and undo_url.
          content:
            image/jpeg:
              schema:
                type: string
                format: binary
        default:
          $ref: '#/components/responses/Problem'
      x-v1: get_identifications_id_thumb
      x-piece: M.11d
  /storages/{id}/restore:
    post:
      operationId: post_storages_by_id_restore
      summary: Restore an archived record.
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Restored.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenStorage'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_storages_by_id_restore
      x-piece: M.11c
  /lots/{id}/restore:
    post:
      operationId: post_lots_by_id_restore
      summary: Restore an archived record.
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Restored.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenLot'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_lots_by_id_restore
      x-piece: M.11c
  /places/{id}/restore:
    post:
      operationId: post_places_by_id_restore
      summary: Restore an archived record.
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Restored.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenPlace'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_places_by_id_restore
      x-piece: M.11c
  /flags/{id}/restore:
    post:
      operationId: post_flags_by_id_restore
      summary: Restore an archived record.
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Restored.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenFlag'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_flags_by_id_restore
      x-piece: M.11c
  /instruction-files/{id}/restore:
    post:
      operationId: post_instruction_files_by_id_restore
      summary: Restore an archived record.
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id_int'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Restored.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenInstructionFile'
        default:
          $ref: '#/components/responses/Problem'
      x-v1: post_instruction_files_by_id_restore
      x-piece: M.11c
  /items/{id}/detail:
    get:
      operationId: get_items_by_id_detail
      summary: 'Item detail: properties, counts, owned and wished summary, prices, matches (what v1''s GET /items/{type}/{no} returned).'
      tags:
      - Items
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItemDetail'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /sets/by-number/{no}:
    get:
      operationId: get_sets_by_number_by_no
      summary: Find the item for a set number; the same item body as /items/{id} (decision 2). A set number is the same at both providers. Several items
        answer 409 ambiguous with the candidates, none 404.
      tags:
      - Identity
      security:
      - bearerAuth:
        - read
      parameters:
      - name: 'no'
        in: path
        required: true
        schema:
          type: string
          maxLength: 64
        description: The number in the provider space.
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      responses:
        '200':
          description: The item. With a color, data.color is the resolved Brick Work colour.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItem'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Ambiguous'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-mcp-tool: get_set_by_number
      x-piece: M.11a
  /parts/by-number/{no}:
    get:
      operationId: get_parts_by_number_by_no
      summary: Find the item for a part number; the same item body as /items/{id} (decision 2). Default provider bricklink; provider=rebrickable for Rebrickable
        numbers. Several items answer 409 ambiguous with the candidates, none 404.
      tags:
      - Identity
      security:
      - bearerAuth:
        - read
      parameters:
      - name: 'no'
        in: path
        required: true
        schema:
          type: string
          maxLength: 64
        description: The number in the provider space.
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      responses:
        '200':
          description: The item. With a color, data.color is the resolved Brick Work colour.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItem'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Ambiguous'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-mcp-tool: get_part_by_number
      x-piece: M.11a
  /minifigures/by-number/{no}:
    get:
      operationId: get_minifigures_by_number_by_no
      summary: Find the item for a minifigure number; the same item body as /items/{id} (decision 2). Default provider bricklink; provider=rebrickable for
        Rebrickable numbers. Several items answer 409 ambiguous with the candidates, none 404.
      tags:
      - Identity
      security:
      - bearerAuth:
        - read
      parameters:
      - name: 'no'
        in: path
        required: true
        schema:
          type: string
          maxLength: 64
        description: The number in the provider space.
      - $ref: '#/components/parameters/Q_provider'
      - $ref: '#/components/parameters/Q_color'
      responses:
        '200':
          description: The item. With a color, data.color is the resolved Brick Work colour.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItem'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Ambiguous'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-mcp-tool: get_minifigure_by_number
      x-piece: M.11a
  /lookup:
    get:
      operationId: get_lookup
      summary: 'Find the item for any provider number: provider, kind and key (and a colour in the provider space). Same body and errors as the by-number
        paths.'
      tags:
      - Identity
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Q_provider'
      - name: kind
        in: query
        required: true
        schema:
          $ref: '#/components/schemas/Kind'
      - name: key
        in: query
        required: true
        schema:
          type: string
          maxLength: 64
      - $ref: '#/components/parameters/Q_color'
      responses:
        '200':
          description: The item. With a color, data.color is the resolved Brick Work colour.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OneItem'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Ambiguous'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-mcp-tool: lookup_item
      x-piece: M.11a
  /items/{id}/links:
    get:
      operationId: get_items_by_id_links
      summary: The item's provider links with status, method, origin, preferred and colour scope (design 3.2), to-check candidates included.
      tags:
      - Identity
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfItemLink'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
    put:
      operationId: put_items_by_id_links
      summary: Set one manual link of the item, or make one preferred for its colour scope (design 3.2). Idempotent per (provider, type, number, colour).
      tags:
      - Identity
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ItemLinkWrite'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenItemLink'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Merged'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /items/{id}/provider-status:
    get:
      operationId: get_items_by_id_provider_status
      summary: 'What is known about the item at a provider when there is no key: looked and nothing found, to check without candidate, kind differs (design
        3.2).'
      tags:
      - Identity
      security:
      - bearerAuth:
        - read
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfItemProviderStatus'
        '307':
          $ref: '#/components/responses/Moved'
        '404':
          $ref: '#/components/responses/NotFound'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /links:
    get:
      operationId: get_links
      summary: 'Links and provider statuses across items, by status: status=to_check is the list that replaces v1''s /unresolved.'
      tags:
      - Identity
      security:
      - bearerAuth:
        - read
      parameters:
      - name: status
        in: query
        schema:
          type: string
          enum:
          - matched
          - inferred
          - manual
          - to_check
      - name: provider
        in: query
        schema:
          type: string
      - $ref: '#/components/parameters/Q_item_kind'
      - $ref: '#/components/parameters/Cursor'
      - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListOfLinkRow'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11b
  /items/{id}/merge:
    post:
      operationId: post_items_by_id_merge
      summary: 'Merge this local item into a survivor (design 3.6): every reference moves, the id answers 307 to the survivor afterwards. Refused for a
        live catalogue item.'
      tags:
      - Identity
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MergeRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenMerge'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /items/{id}/unmerge:
    post:
      operationId: post_items_by_id_unmerge
      summary: 'Undo a merge by its receipt (design 3.6): the merged id answers for itself again. Refused if a moved row changed since.'
      tags:
      - Identity
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UnmergeRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenMerge'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /items/{id}/change-variant:
    post:
      operationId: post_items_by_id_change_variant
      summary: 'Change the variant (#151): everything owned of this catalogue item (loose stock, wishes, figure lines of copies with their part lists) moves to another item of the same kind, and BrickLink''s number becomes the other item''s preferred link. One event; Undo puts every row back. Refused for a merged item, another kind, a set, a job in flight, and rows that would meet on a key.'
      tags:
      - Identity
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangeVariantRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenVariantChange'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /items/{id}/build:
    post:
      operationId: post_items_by_id_build
      summary: 'Build it (#9): make a copy of this set from the loose stock, moving the matching parts and whole figures into it; one event, Undo puts the stock back and archives the copy.'
      description: 'Builds one copy of the set from the catalogue''s latest Rebrickable part list: every part line and whole figure the chosen stock covers is
        moved out of it into the copy (the largest usable row first, then the lowest id), the rest is recorded as missing on the copy, and one
        `stock_transfer` row per move is kept. The stock is the one Build Scout counts (`GET /planning/build-scout`): damaged rows give nothing unless
        `damaged` is true. Refused with 422 for a set made of other sets, a set with no part list and sources that hold nothing the set needs. The event
        is `copy` / `make_from_stock`; Undo (`POST /events/{id}/undo`) puts the stock back and archives the copy, and is refused when the copy or the stock changed since.'
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_item_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BuildFromStockRequest'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenBuild'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /copies/{id}/inventory:
    post:
      operationId: post_copies_by_id_inventory
      summary: 'Switch the copy''s part list in place (design 4.4): to Rebrickable (a version) or BrickLink. A BrickLink switch is pending until its fetch
        job lands.'
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKeyRequired'
      - $ref: '#/components/parameters/IfMatch'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CopyInventorySwitch'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '202':
          description: 'Pending: the BrickLink list is being fetched (the Job is data.inventory.pending).'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          $ref: '#/components/responses/PreconditionFailed'
        '422':
          $ref: '#/components/responses/Invalid'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
  /copies/{id}/inventory/pending:
    delete:
      operationId: delete_copies_by_id_inventory_pending
      summary: 'Cancel a pending BrickLink switch (design 4.4): the copy keeps its current list.'
      tags:
      - Copies
      security:
      - bearerAuth:
        - write
      parameters:
      - $ref: '#/components/parameters/Path_id'
      - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WrittenCopy'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        default:
          $ref: '#/components/responses/Problem'
      x-piece: M.11c
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Authorization: Bearer <token>. Scopes: read, write, admin (admin includes write, write includes read). Listed per operation.'
  parameters:
    Cursor:
      name: cursor
      in: query
      schema:
        type: string
      description: Opaque cursor from page.next_cursor.
    Limit:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 200
        default: 50
    DirectionNewest:
      name: direction
      in: query
      schema:
        type: string
        enum:
        - asc
        - desc
        default: desc
    Direction:
      name: direction
      in: query
      schema:
        type: string
        enum:
        - asc
        - desc
        default: asc
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      schema:
        type: string
        maxLength: 80
        pattern: ^[A-Za-z0-9-]{1,80}$
      description: Optional replay protection (see api-v1.md).
    IdempotencyKeyRequired:
      name: Idempotency-Key
      in: header
      required: true
      schema:
        type: string
        maxLength: 80
        pattern: ^[A-Za-z0-9-]{1,80}$
      description: 'Required: the operation creates records or moves quantities.'
    IfMatch:
      name: If-Match
      in: header
      required: false
      schema:
        type: string
      description: ETag from the last read; mismatch gives 412.
    Q_q:
      name: q
      in: query
      schema:
        type: string
      description: Text over name, number, colour, category, theme, year (case-insensitive substring, as the web lists).
    Q_sort:
      name: sort
      in: query
      schema:
        type: string
      description: One of number, name, year, quantity, missing, damaged, used_price, colour, added. Default number; planning defaults to ranking (core group,
        pin, ratio and gain order). `added` (on /copies) is when the copy was added to Brick Work.
    Path_color_id_int:
      name: color_id
      in: path
      required: true
      schema:
        type: integer
    Q_theme:
      name: theme
      in: query
      schema:
        type: string
      description: Theme name.
    Q_category:
      name: category
      in: query
      schema:
        type: string
      description: Category name.
    Q_year:
      name: year
      in: query
      schema:
        type: string
      description: Year.
    Q_owned:
      name: owned
      in: query
      schema:
        type: string
      description: true to list only owned items.
    Path_id_int:
      name: id
      in: path
      required: true
      schema:
        type: integer
    Path_image_id:
      name: id
      in: path
      required: true
      description: A cached provider picture's number, or an own photo's 32-character hex id (`Image.id`).
      schema:
        oneOf:
        - type: integer
        - type: string
          pattern: ^[0-9a-f]{32}$
    Q_condition:
      name: condition
      in: query
      schema:
        type: string
      description: new, used, damaged for copies and stock; new, used, any for wishes.
    Q_status:
      name: status
      in: query
      schema:
        type: string
      description: Completeness sealed, complete, incomplete or unknown (copies); order status (orders).
    Q_storage:
      name: storage
      in: query
      schema:
        type: string
      description: Storage id, or null for Not stored.
    Q_place:
      name: place
      in: query
      schema:
        type: string
      description: Purchase location id, or null.
    Q_flag:
      name: flag
      in: query
      schema:
        type: string
      description: Flag id.
    Q_lot:
      name: lot
      in: query
      schema:
        type: string
      description: Lot id, or null for none.
    Q_problem:
      name: problem
      in: query
      schema:
        type: string
      description: missing or damaged.
    Q_duplicates:
      name: duplicates
      in: query
      schema:
        type: string
      description: true for several copies, false for one.
    Q_archived:
      name: archived
      in: query
      schema:
        type: string
      description: true or include (default exclude), or only.
    Path_id:
      name: id
      in: path
      required: true
      schema:
        type: string
    Path_stock_id:
      name: stock_id
      in: path
      required: true
      schema:
        type: string
    Q_spare:
      name: spare
      in: query
      schema:
        type: string
      description: 0 or 1.
    Q_parent:
      name: parent
      in: query
      schema:
        type: string
      description: Parent figure number.
    Path_part_id_int:
      name: part_id
      in: path
      required: true
      schema:
        type: integer
    Q_inventory:
      name: inventory
      in: query
      schema:
        type: string
      description: parts, figures or instructions (web Inventory tabs).
    Q_kind:
      name: kind
      in: query
      schema:
        type: string
      description: Kind filter.
    Q_source:
      name: source
      in: query
      schema:
        type: string
      description: Source key.
    Q_source_id:
      name: source_id
      in: query
      schema:
        type: string
      description: Source identifier.
    Q_copy_id:
      name: copy_id
      in: query
      schema:
        type: string
      description: Copy id (repeatable where an export).
    Q_completes:
      name: completes
      in: query
      schema:
        type: string
      description: true to keep only matches that complete a copy.
    Q_has_file:
      name: has_file
      in: query
      schema:
        type: string
      description: true to keep the file records whose PDF is on disk, false those whose PDF is missing from the media folder.
    Q_guide:
      name: guide
      in: query
      schema:
        type: string
      description: sold, stock, retail, manual or valuation.
    Q_under_max:
      name: under_max
      in: query
      schema:
        type: string
      description: true to keep wishes priced under their maximum.
    Q_move_to_unstored:
      name: move_to_unstored
      in: query
      schema:
        type: string
      description: true to move contents to Not stored when archiving.
    Q_confirm:
      name: confirm
      in: query
      schema:
        type: string
      description: The reference count shown by the preceding read; deletion is refused if it differs.
    Q_bricklink_order_id:
      name: bricklink_order_id
      in: query
      schema:
        type: string
      description: BrickLink order number.
    Path_line_id_int:
      name: line_id
      in: path
      required: true
      schema:
        type: integer
    Path_doc_id_int:
      name: doc_id
      in: path
      required: true
      schema:
        type: integer
    Q_entity:
      name: entity
      in: query
      schema:
        type: string
      description: Event entity prefix.
    Q_field:
      name: field
      in: query
      schema:
        type: string
      description: Event field.
    Q_via:
      name: via
      in: query
      schema:
        type: string
      description: app, cli, api, import or migration.
    Q_since:
      name: since
      in: query
      schema:
        type: string
      description: ISO-8601 timestamp; events at or after.
    Q_undoable:
      name: undoable
      in: query
      schema:
        type: string
      description: true to keep events that can still be undone.
    Q_state:
      name: state
      in: query
      schema:
        type: string
      description: Job state.
    Q_failed:
      name: failed
      in: query
      schema:
        type: string
      description: true for jobs with a failed step.
    Path_source:
      name: source
      in: path
      required: true
      schema:
        type: string
    Path_item_id:
      name: id
      in: path
      required: true
      x-mcp-item: true
      schema:
        type: integer
        minimum: 1
      description: 'Brick Work item id. Ids are per install (design 3.1): store numbers, not ids.'
    Path_set_item_id:
      name: set_id
      in: path
      required: true
      x-mcp-item: true
      schema:
        type: integer
        minimum: 1
      description: Brick Work item id of the set.
    Path_figure_item_id:
      name: item_id
      in: path
      required: true
      x-mcp-item: true
      schema:
        type: integer
        minimum: 1
      description: Brick Work item id of the figure.
    Path_wish_id:
      name: id
      in: path
      required: true
      schema:
        type: string
      description: Wish uuid (Q6).
    Path_wishlist_id:
      name: id
      in: path
      required: true
      schema:
        type: string
      description: Wishlist id.
    Q_item_kind:
      name: kind
      in: query
      schema:
        $ref: '#/components/schemas/Kind'
      description: Item kind.
    Q_provider:
      name: provider
      in: query
      schema:
        type: string
        enum:
        - bricklink
        - rebrickable
        - brickwork
        default: bricklink
      description: 'The space numbers and colours are given in (decision 3 and 4): bricklink (default), rebrickable, or brickwork (Brick Work ids; colours
        on /items/{id} paths).'
    Q_number:
      name: number
      in: query
      schema:
        type: string
      description: Item number in the provider space.
    Q_color:
      name: color
      in: query
      schema:
        type: integer
      description: Colour id in the provider space (decision 4).
  responses:
    Problem:
      description: Any other error, including 401 unauthorized, 403 forbidden and 5xx. Always application/problem+json with a stable code.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unauthorized:
      description: No token, bad token, revoked or expired token.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Forbidden:
      description: Token lacks the scope, or the instance is read only.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotFound:
      description: No such record.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    MethodNotAllowed:
      description: Method not supported for this path (405 method_not_allowed).
      headers:
        Allow:
          description: Supported HTTP methods for this path.
          required: true
          schema:
            type: string
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Conflict:
      description: State changed, duplicate, idempotency key reused with another body, or Undo blocked by a later change.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Invalid:
      description: Validation failed; errors[] names the fields.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    PreconditionFailed:
      description: If-Match did not match the current ETag.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    DependencyFailed:
      description: Key, source or catalogue not configured (source_not_configured, source_disabled, catalogue_not_loaded).
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    BudgetExhausted:
      description: Daily budget or remote throttle; Retry-After header and retry_after field; job_id when a job holds the call.
      headers:
        Retry-After:
          schema:
            type: integer
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Moved:
      description: 'The id was merged away: 307 to the survivor, never cached (merges can be undone).'
      headers:
        Location:
          schema:
            type: string
        Cache-Control:
          schema:
            type: string
            enum:
            - no-store
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Ambiguous:
      description: The number names several items; candidates lists them.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Merged:
      description: The id was merged away; survivor names the live item. Write to it.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    Unidentified:
      description: The number resolves to no item and the request cannot create one.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotImplemented:
      description: The operation arrives with the piece named in the body.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  schemas:
    FieldError:
      type: object
      properties:
        field:
          type: string
        code:
          type: string
        message:
          type: string
      required:
      - field
      - code
    PageInfo:
      type: object
      properties:
        next_cursor:
          type:
          - string
          - 'null'
        limit:
          type: integer
        total:
          type:
          - integer
          - 'null'
      required:
      - limit
    Health:
      type: object
      properties:
        status:
          type: string
          enum:
          - ok
          - degraded
        api:
          type: string
        app:
          type: string
          description: The running Brick Work version, as in /version.
        schema:
          type: string
        catalogue_loaded:
          type: boolean
      required:
      - status
      - api
    Version:
      type: object
      properties:
        api:
          type: string
        app:
          type: string
        schema:
          type: string
        read_only:
          type: boolean
        features:
          type: array
          items:
            type: string
      required:
      - api
    Me:
      type: object
      properties:
        name:
          type: string
        scopes:
          type: array
          items:
            type: string
        expires_at:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - name
      - scopes
    Token:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        scopes:
          type: array
          items:
            type: string
        created_at:
          type: string
          format: date-time
        last_used_at:
          type:
          - string
          - 'null'
          format: date-time
        expires_at:
          type:
          - string
          - 'null'
          format: date-time
        revoked_at:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - id
      - name
      - scopes
    TokenCreate:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 80
        scopes:
          type: array
          minItems: 1
          items:
            type: string
            enum:
            - read
            - write
            - admin
        expires_at:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - name
      - scopes
    TokenCreated:
      type: object
      properties:
        token:
          $ref: '#/components/schemas/Token'
        secret:
          type:
          - string
          - 'null'
      required:
      - token
      - secret
      description: secret is returned once and never again; the answer a replay of the same request gets has it null (the replay record never holds it).
    CatalogueItem:
      type: object
      properties:
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        year:
          type:
          - integer
          - 'null'
        owned:
          type: integer
        wished:
          type: boolean
        category:
          type:
          - string
          - 'null'
        theme:
          type:
          - string
          - 'null'
          description: The Rebrickable theme of a set or minifigure from the catalogue (a part has none). Item properties fetched later may name another.
      required:
      - item
    ItemDetail:
      type: object
      properties:
        item:
          $ref: '#/components/schemas/Item'
        properties: {}
        counts:
          type: object
          properties:
            owned:
              type: integer
            wished:
              type: boolean
          required:
          - owned
          - wished
        copies:
          type: array
          items:
            $ref: '#/components/schemas/Copy'
        stock:
          type: array
          items:
            $ref: '#/components/schemas/Stock'
        wishes:
          type: array
          items:
            $ref: '#/components/schemas/Wish'
        prices: {}
        inventory:
          type: array
          items:
            $ref: '#/components/schemas/InventoryLine'
        links:
          type: array
          items:
            $ref: '#/components/schemas/ItemLink'
        used_in:
          description: The live copies that hold the item (a part or a figure), as `GET /items/{id}/used-in`.
          type: array
          items:
            $ref: '#/components/schemas/UsedIn'
        gaps:
          description: The gaps on this item, and (for a set) the gaps of its copies, as `GET /gaps`.
          type: array
          items:
            $ref: '#/components/schemas/Gap'
        matches:
          description: The loose stock that fills those gaps, as `GET /matches`.
          type: array
          items:
            $ref: '#/components/schemas/Match'
      required:
      - item
    InventoryLine:
      type: object
      properties:
        child:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        quantity:
          type:
          - integer
          - 'null'
        extra_quantity:
          type: integer
        source:
          type: string
    UsedIn:
      type: object
      properties:
        copy_id:
          type: string
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        quantity:
          type:
          - integer
          - 'null'
        missing:
          type:
          - integer
          - 'null'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
    Image:
      type: object
      properties:
        id:
          description: The picture number of a cached provider picture, the 32-character hex id of an own photo.
          oneOf:
          - type: integer
          - type: string
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        source:
          type: string
        kind:
          type: string
          enum:
          - photo
          - render
          - box
          - booklet
          - own
        width:
          type:
          - integer
          - 'null'
        height:
          type:
          - integer
          - 'null'
        fetched_at:
          type:
          - string
          - 'null'
          format: date-time
        copy_id:
          type:
          - string
          - 'null'
        stock_id:
          type:
          - string
          - 'null'
        caption:
          type:
          - string
          - 'null'
        content_url:
          type: string
      required:
      - id
    ImportRequest:
      type: object
      additionalProperties: false
      properties:
        steps:
          type: array
          minItems: 1
          items:
            type: string
            enum:
            - identity
            - inventory
            - matching
            - pictures
            - metadata
            - market_price
      description: Optional step subset; default is the stored import order for the item's kind. The sources of a step are the stored order of its kind.
    CopyCreate:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        quantity:
          type: integer
        condition:
          type: string
          enum:
          - new
          - used
        completeness:
          type: string
          enum:
          - sealed
          - complete
          - incomplete
        decision:
          type: string
          enum:
          - another
          - skip
        storage_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
      required:
      - item
    CopyPatch:
      type: object
      properties:
        condition:
          type: string
          enum:
          - new
          - used
        completeness:
          type: string
          enum:
          - sealed
          - complete
          - incomplete
        completeness_source:
          type: string
          enum:
          - manual
          - derived
        storage_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        current_value:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        current_value_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        note:
          type:
          - string
          - 'null'
      description: Only these fields; at least one. null clears.
    FlagSet:
      type: object
      properties:
        flags:
          type: array
          items:
            type: string
      required:
      - flags
    Pin:
      type: object
      properties:
        pinned:
          type: boolean
      required:
      - pinned
    Checked:
      type: object
      properties:
        checked:
          type: boolean
      required:
      - checked
      additionalProperties: false
    Completeness:
      type: object
      properties:
        stored:
          type:
          - string
          - 'null'
          enum:
          - sealed
          - complete
          - incomplete
          - null
        completeness_source:
          type: string
          enum:
          - manual
          - derived
        derived:
          type:
          - string
          - 'null'
          enum:
          - sealed
          - complete
          - incomplete
          - null
        checked:
          type: boolean
        missing:
          type: integer
        damaged:
          type: integer
        missing_figures:
          type: integer
      required:
      - stored
    CheckState:
      type: object
      properties:
        session:
          description: The saved part-check session (id, order, cursor, answers, misses, undo, finished, sort, spares, scope, saved_at; `scope` is `missing` for a missing-only run, `skipped` for a walk of the skipped parts, null for the whole set), or null when none was started.
        rows:
          description: The sequence of the check. One entry per required part line (kind part), whole figure (figure) and spare line (spare) with token, id, item, name, color, quantity, missing, damaged, checked and image_id; a figure carries parts_lines and parts_missing.
    CheckAction:
      type: object
      properties:
        action:
          type: string
          enum:
          - start
          - answer
          - found_one
          - skip
          - select
          - back
          - next
          - spares
          - recheck
          - finish
          - undo
        token:
          type: string
        session:
          type: string
        found:
          type: integer
        include:
          type: boolean
        checked:
          type: boolean
        order:
          type: string
          enum:
          - inventory
          - largest
          - colour
        scope:
          type: string
          description: 'start only: `all` walks the whole set (a fresh start without `scope` does too); `missing` walks only the parts the last check left missing (the others keep their answers; refused with 422 when none is missing). Left out, a start resumes the running check; a named scope that is not the running one replaces it (Undo brings it back).'
          enum:
          - all
          - missing
        tokens:
          type: array
          description: 'recheck only: the skipped lines to walk (default: every skipped one).'
          items:
            type: string
      required:
      - action
    Gap:
      description: What a copy or a loose figure lacks. For a missing booklet or box (`instructions`, `box`) the item is the copy's set and `target_id` is the copy id; for a part, a figure or a loose figure's part it is the item missing and `target_id` the line id.
      type: object
      properties:
        copy_id:
          type: string
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        target:
          type: string
          enum:
          - part
          - figure
          - stock-part
          - instructions
          - box
        target_id: {}
        need:
          type: integer
        unresolved:
          type: boolean
    Match:
      type: object
      properties:
        source_id:
          type: string
        copy_id:
          type: string
        target:
          type: string
        target_id: {}
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        have:
          type: integer
        suggested:
          type: integer
        completes:
          type: boolean
    Take:
      type: object
      description: A part (P) needs its colour; a whole minifigure (M) has none (omit color_id or send null).
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        quantity:
          type: integer
      required:
      - item
      - quantity
    Give:
      type: object
      properties:
        copy_id:
          type: string
        target:
          type: string
          enum:
          - part
          - figure
          - stock-part
          - instructions
          - box
        target_id: {}
        quantity:
          type: integer
      required:
      - copy_id
      - target
      - target_id
      - quantity
    Booklets:
      type: object
      properties:
        text:
          type: string
        quantity:
          type: integer
      required:
      - text
    Found:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        destination:
          type: string
          enum:
          - set
          - loose
          - list
        quantity:
          type: integer
        assignments: {}
      required:
      - item
      - color
      - destination
      - quantity
    Receipt:
      type: object
      properties:
        event_id:
          type: integer
        message:
          type: string
      required:
      - event_id
    CopyPart:
      type: object
      properties:
        id:
          type: integer
        copy_id:
          type: string
        parent_minifig:
          oneOf:
          - $ref: '#/components/schemas/Item'
          - type: 'null'
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        spare:
          type:
          - integer
          - 'null'
        quantity:
          type:
          - integer
          - 'null'
        missing:
          type:
          - integer
          - 'null'
        damaged:
          type:
          - integer
          - 'null'
        checked:
          type:
          - boolean
          - 'null'
      required:
      - id
    CopyPartPatch:
      type: object
      properties:
        missing:
          type: integer
          minimum: 0
        damaged:
          type: integer
          minimum: 0
        checked:
          type: boolean
      additionalProperties: false
      minProperties: 1
    CopyPartBulk:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/CopyPartBulkItem'
          minItems: 1
          maxItems: 500
        mode:
          type: string
          enum:
          - set
          - add
          default: set
        dry_run:
          type: boolean
          default: false
      required:
      - items
      additionalProperties: false
    CopyPartBulkItem:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        missing:
          type: integer
          minimum: 0
      required:
      - item
      - color
      - missing
      additionalProperties: false
    BulkResult:
      type: object
      properties:
        applied:
          type: integer
        skipped:
          type: array
          items:
            $ref: '#/components/schemas/FieldError'
        dry_run:
          type: boolean
        event_id:
          type:
          - integer
          - 'null'
    CopyFigure:
      type: object
      properties:
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        quantity:
          type:
          - integer
          - 'null'
        missing:
          type:
          - integer
          - 'null'
        parts_lines:
          type: integer
        parts_missing:
          type: integer
    CopyFigurePatch:
      type: object
      properties:
        missing:
          type: integer
          minimum: 0
      required:
      - missing
      additionalProperties: false
    Stock:
      type: object
      properties:
        id:
          type: string
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        quantity:
          type:
          - integer
          - 'null'
        condition:
          type:
          - string
          - 'null'
          enum:
          - new
          - used
          - damaged
          - null
        storage_id:
          type:
          - string
          - 'null'
        lot_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        note:
          type:
          - string
          - 'null'
        created_at:
          type:
          - string
          - 'null'
          format: date-time
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
        archived_at:
          type:
          - string
          - 'null'
          format: date-time
        missing:
          type:
          - integer
          - 'null'
        damaged:
          type:
          - integer
          - 'null'
        flags:
          type: array
          items:
            type: string
        merged_ids:
          type: array
          items:
            type: string
        etag:
          type: string
        image_id:
          type:
          - integer
          - 'null'
      required:
      - id
      - item
    StockCreate:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        quantity:
          type: integer
        condition:
          type: string
          enum:
          - new
          - used
          - damaged
        storage_id:
          type:
          - string
          - 'null'
        lot_id:
          type:
          - string
          - 'null'
        note:
          type:
          - string
          - 'null'
      required:
      - item
      - quantity
    StockPatch:
      type: object
      properties:
        condition:
          type: string
          enum:
          - new
          - used
          - damaged
        storage_id:
          type:
          - string
          - 'null'
        lot_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        note:
          type:
          - string
          - 'null'
    LooseFigurePart:
      type: object
      properties:
        stock_id:
          type: string
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        spare:
          type:
          - integer
          - 'null'
        quantity:
          type:
          - integer
          - 'null'
        missing:
          type:
          - integer
          - 'null'
        damaged:
          type:
          - integer
          - 'null'
        checked:
          type:
          - boolean
          - 'null'
    LooseFigurePartPatch:
      type: object
      properties:
        parts:
          type: array
          items:
            $ref: '#/components/schemas/LooseFigurePartKey'
          minItems: 1
          maxItems: 500
      required:
      - parts
      additionalProperties: false
    LooseFigurePartKey:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        spare:
          type:
          - integer
          - 'null'
          description: Exact stored spare key; null and zero are distinct.
        missing:
          type: integer
          minimum: 0
        damaged:
          type: integer
          minimum: 0
        checked:
          type: boolean
      required:
      - item
      - color
      - spare
      additionalProperties: false
    MinifigureRow:
      type: object
      properties:
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        theme:
          type:
          - string
          - 'null'
        year:
          type:
          - integer
          - 'null'
        quantity:
          type: integer
        in_sets:
          type: integer
        missing:
          type: integer
        damaged:
          type: integer
        image_id:
          type:
          - integer
          - 'null'
    InstructionFile:
      type: object
      properties:
        archived_at:
          type:
          - string
          - 'null'
        id:
          type: integer
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        label:
          type:
          - string
          - 'null'
        added_at:
          type:
          - string
          - 'null'
          format: date-time
        content_url:
          type:
          - string
          - 'null'
      required:
      - id
    InstructionUpload:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        label:
          type: string
        file:
          type: string
      required:
      - item
      - label
      - file
      description: multipart/form-data; file is a PDF of at most 20 MB.
    InstructionPatch:
      type: object
      properties:
        label:
          type: string
      required:
      - label
    PriceObservation:
      type: object
      properties:
        id:
          type: integer
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        condition:
          type:
          - string
          - 'null'
          enum:
          - new
          - used
          - null
        guide:
          type: string
          enum:
          - sold
          - stock
          - retail
          - manual
          - valuation
        slot:
          type:
          - string
          - 'null'
        region:
          type:
          - string
          - 'null'
        currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        qty:
          type:
          - integer
          - 'null'
        sold:
          type:
          - integer
          - 'null'
        min:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        max:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        source:
          type: string
        observed_at:
          type:
          - string
          - 'null'
          format: date-time
        error:
          type:
          - string
          - 'null'
      required:
      - id
    PriceCurrent:
      type: object
      properties:
        observation:
          $ref: '#/components/schemas/PriceObservation'
        age_days:
          type:
          - number
          - 'null'
        stale:
          type: boolean
    ItemPrices:
      type: object
      properties:
        current:
          type: array
          items:
            $ref: '#/components/schemas/PriceCurrent'
        records:
          type: array
          items:
            $ref: '#/components/schemas/PriceObservation'
    PriceCreate:
      type: object
      properties:
        condition:
          type: string
          enum:
          - new
          - used
        guide:
          type: string
          enum:
          - manual
          - valuation
        price:
          type: string
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        currency:
          type: string
          pattern: ^[A-Z]{3,8}$
        slot:
          type:
          - string
          - 'null'
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        observed_at:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - condition
      - guide
      - price
      - currency
      additionalProperties: false
    PriceBatch:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/PriceBatchItem'
          minItems: 1
          maxItems: 500
      required:
      - items
      additionalProperties: false
    PriceBatchItem:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        condition:
          type: string
          enum:
          - new
          - used
        guide:
          type: string
          enum:
          - manual
          - valuation
        price:
          type: string
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        currency:
          type: string
          pattern: ^[A-Z]{3,8}$
        observed_at:
          type:
          - string
          - 'null'
          format: date-time
        slot:
          type:
          - string
          - 'null'
      required:
      - item
      - condition
      - guide
      - price
      - currency
      additionalProperties: false
    RefreshRequest:
      type: object
      properties: {}
      additionalProperties: false
      description: Queue the shared market_price step for the whole item; variant selection belongs to the pipeline. No network call before queueing.
    StaleItem:
      type: object
      properties:
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        condition:
          type:
          - string
          - 'null'
        source_table:
          description: Where the held or wanted line is, by table.
          type: string
          enum:
          - copy
          - stock
          - wish
    Wishlist:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        sort:
          type: integer
        count:
          type: integer
        note:
          type:
          - string
          - 'null'
        archived_at:
          type:
          - string
          - 'null'
        created_at:
          type:
          - string
          - 'null'
        bricklink_id:
          type:
          - string
          - 'null'
    WishlistCreate:
      type: object
      properties:
        name:
          type: string
        sort:
          type: integer
        note:
          type:
          - string
          - 'null'
        bricklink_id:
          type:
          - string
          - 'null'
      required:
      - name
    WishlistPatch:
      type: object
      properties:
        name:
          type: string
        sort:
          type: integer
        note:
          type:
          - string
          - 'null'
        bricklink_id:
          type:
          - string
          - 'null'
      minProperties: 1
    WishlistTransfer:
      type: object
      required:
      - ids
      properties:
        ids:
          type: array
          minItems: 1
          maxItems: 500
          items:
            type: string
        copy:
          type: boolean
          default: false
    ListOfWishlist:
      properties:
        data:
          items:
            $ref: '#/components/schemas/Wishlist'
          type: array
        page:
          $ref: '#/components/schemas/PageInfo'
      required:
      - data
      - page
      type: object
    OneWishlist:
      properties:
        data:
          $ref: '#/components/schemas/Wishlist'
      required:
      - data
      type: object
    WrittenWishlist:
      properties:
        data:
          $ref: '#/components/schemas/Wishlist'
        event_id:
          type: integer
        idempotent_replay:
          type: boolean
        undo_url:
          type: string
      required:
      - data
      - event_id
      type: object
    Wish:
      type: object
      properties:
        qty_filled:
          type: integer
          description: 'How many of the wished quantity you have (#35): qty_filled_manual when set, else derived from owned stock.'
        qty_filled_source:
          type: string
          enum:
          - derived
          - manual
        qty_filled_manual:
          type:
          - integer
          - 'null'
        list_id:
          type: string
          description: Target wishlist id; defaults to default on create.
        id:
          type: string
          description: uuid (Q6).
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        quantity:
          type: integer
        max_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        max_price_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        max_price_boxed:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float. The max for a quote with box (a set's slot boxed); without it such a quote
            is held against max_price.
        max_price_boxed_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        condition:
          type:
          - string
          - 'null'
          enum:
          - new
          - used
          - any
          - null
        note:
          type:
          - string
          - 'null'
        added_at:
          type:
          - string
          - 'null'
          format: date-time
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
        archived_at:
          type:
          - string
          - 'null'
          format: date-time
        under_max:
          type:
          - boolean
          - 'null'
        under_max_boxed:
          type:
          - boolean
          - 'null'
          description: A set's current quote with box against max_price_boxed, or max_price when that is not set; null when either
            is missing or the currencies differ without a rate.
        current_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        flags:
          type: array
          items:
            type: string
        etag:
          type: string
        image_id:
          type:
          - integer
          - 'null'
      required:
      - id
      - item
      - quantity
    WishCreate:
      type: object
      properties:
        list_id:
          type: string
          description: Target wishlist id; defaults to default on create.
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        quantity:
          type: integer
        condition:
          type: string
          enum:
          - new
          - used
          - any
        note:
          type:
          - string
          - 'null'
        max_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        max_price_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        max_price_boxed:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float. The max for a quote with box (a set's slot boxed); without it such a quote
            is held against max_price.
        max_price_boxed_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        decision:
          type: string
          enum:
          - another
          - skip
      required:
      - item
    WishPatch:
      type: object
      properties:
        qty_filled_manual:
          type:
          - integer
          - 'null'
          description: Override the filled quantity; null goes back to the derived count.
        list_id:
          type: string
          description: Target wishlist id; defaults to default on create.
        quantity:
          type: integer
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
        condition:
          type: string
          enum:
          - new
          - used
          - any
        max_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        max_price_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        max_price_boxed:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float. The max for a quote with box (a set's slot boxed); without it such a quote
            is held against max_price.
        max_price_boxed_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        note:
          type:
          - string
          - 'null'
    WishToOwned:
      type: object
      properties:
        quantity:
          type: integer
        condition:
          type: string
          enum:
          - new
          - used
        completeness:
          type: string
          enum:
          - sealed
          - complete
          - incomplete
    Storage:
      type: object
      properties:
        id:
          description: The storage id. The virtual location "Not stored" has the id `unstored` (in a filter, `null` means not stored).
          type:
          - string
          - 'null'
        name:
          type:
          - string
          - 'null'
        copies:
          type: integer
        entries:
          type: integer
        pieces:
          type: integer
        lots:
          type: integer
        figures:
          type: integer
        part_lots:
          type: integer
        type:
          type:
          - string
          - 'null'
          enum:
          - Box
          - Shelf
          - Drawer
          - Bin
          - Bag
          - Case
          - Cabinet
          - Room
          - Other
          - null
        parent_id:
          type:
          - string
          - 'null'
        parent_name:
          type:
          - string
          - 'null'
        note:
          type:
          - string
          - 'null'
        archived_at:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - id
    StorageDetail:
      type: object
      properties:
        location:
          $ref: '#/components/schemas/Storage'
        rows: {}
    StorageInput:
      type: object
      description: type, parent_id and note are optional; a field left out keeps its value. parent_id is another live storage, never this one or one inside
        it.
      properties:
        name:
          type: string
        type:
          type:
          - string
          - 'null'
          enum:
          - Box
          - Shelf
          - Drawer
          - Bin
          - Bag
          - Case
          - Cabinet
          - Room
          - Other
          - null
        parent_id:
          type:
          - string
          - 'null'
        note:
          type:
          - string
          - 'null'
      required:
      - name
    StorageMove:
      type: object
      properties:
        selections:
          type: array
          items:
            $ref: '#/components/schemas/StorageSelection'
      required:
      - selections
    StorageSelection:
      type: object
      properties:
        entity:
          type: string
          enum:
          - copy
          - stock
          - lot
        id:
          type: string
      required:
      - entity
      - id
    Lot:
      type: object
      properties:
        id:
          type: string
        name:
          type:
          - string
          - 'null'
        note:
          type:
          - string
          - 'null'
        created_at:
          type:
          - string
          - 'null'
          format: date-time
        storage_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        archived_at:
          type:
          - string
          - 'null'
          format: date-time
        entries:
          type: integer
        quantity:
          type: integer
      required:
      - id
    LotDetail:
      type: object
      properties:
        lot:
          $ref: '#/components/schemas/Lot'
        rows:
          type: array
          items:
            $ref: '#/components/schemas/Stock'
    LotCreate:
      type: object
      properties:
        stock_ids:
          type: array
          items:
            type: string
        name:
          type: string
        note:
          type:
          - string
          - 'null'
        storage_id:
          type:
          - string
          - 'null'
      required:
      - stock_ids
      - name
    LotPatch:
      type: object
      properties:
        name:
          type: string
        note:
          type:
          - string
          - 'null'
        storage_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
    Place:
      type: object
      properties:
        archived_at:
          type:
          - string
          - 'null'
        id:
          type: string
        name:
          type:
          - string
          - 'null'
        kind:
          type:
          - string
          - 'null'
        count:
          type: integer
        totals: {}
        orders:
          type: integer
          description: Orders whose store carries this name (derived).
        last_used:
          type:
          - string
          - 'null'
          description: Latest purchase or order date (derived).
      required:
      - id
    Flag:
      type: object
      properties:
        archived_at:
          type:
          - string
          - 'null'
        id:
          type: string
        name:
          type:
          - string
          - 'null'
        kind:
          type: string
          enum:
          - status
          - tag
          - owner
        shown_on_grid:
          type: boolean
        count:
          type: integer
      required:
      - id
    FlagInput:
      type: object
      properties:
        name:
          type: string
        kind:
          type: string
          enum:
          - status
          - tag
          - owner
      required:
      - name
      - kind
    NameInput:
      type: object
      properties:
        name:
          type: string
      required:
      - name
    Deleted:
      type: object
      properties:
        id:
          type:
          - string
          - integer
        archived:
          type: boolean
    Ranking:
      type: object
      properties:
        rows: {}
        settings: {}
    OrderDocument:
      type: object
      additionalProperties: false
      properties:
        id: {type: integer}
        order_id: {type: integer}
        source: {type: string, enum: [email, xml, api]}
        label: {type: [string, 'null']}
        phase: {type: string, enum: [draft, reviewed, saved, undone]}
        created_at: {type: string}
        updated_at: {type: string}
    OrderLine:
      type: object
      additionalProperties: false
      properties:
        id: {type: integer}
        order_id: {type: integer}
        document_id: {type: integer}
        document_phase: {type: string, enum: [draft, reviewed, saved, undone]}
        line_no: {type: integer}
        state: {type: string, enum: [matched, by_hand, confirmed, held]}
        item:
          oneOf:
          - {$ref: '#/components/schemas/Item'}
          - {type: 'null'}
          description: The item the line stands for; null while the importer could not place it (see raw and suggestions).
        color:
          oneOf:
          - {$ref: '#/components/schemas/Color'}
          - {type: 'null'}
        unplaced: {type: boolean}
        unplaced_reason: {type: [string, 'null'], description: 'Why the importer did not place the line, in words ("The BrickLink number is not in the catalogue", "The name matches several items"); null when it is placed, and on a line imported before schema 4.2.'}
        condition: {type: [string, 'null'], enum: [new, used, null]}
        qty: {type: integer}
        unit_price: {type: [string, 'null']}
        line_total: {type: [string, 'null']}
        remark: {type: [string, 'null']}
        raw:
          type: object
          additionalProperties: false
          description: The provider's own words, verbatim.
          properties:
            item_type: {type: [string, 'null']}
            item_no: {type: [string, 'null']}
            color_id: {type: [integer, 'null']}
            color_name: {type: [string, 'null']}
            name: {type: [string, 'null']}
            text: {type: [string, 'null']}
        received: {type: integer}
        allocated: {type: integer}
        paired_line_id: {type: [integer, 'null']}
        suggestions:
          type: array
          description: 'The items an unplaced line could be, for the person to choose from, best first. A line that names several items lists them; a line whose name no item has exactly lists the nearest names of the BrickLink item list (when loaded), the longest name that starts it first, then the names that hold all its words (#155). Never placed by itself.'
          items:
            type: object
            additionalProperties: false
            properties:
              item: {$ref: '#/components/schemas/Item'}
              label: {type: string}
    OrderDestination:
      type: object
      additionalProperties: false
      properties:
        copy_id: {type: string}
        target: {type: string, enum: [part, figure, instructions, box, stock-part]}
        target_id: {type: [integer, string]}
        need: {type: integer}
        item: {$ref: '#/components/schemas/Item'}
        color:
          oneOf:
          - {$ref: '#/components/schemas/Color'}
          - {type: 'null'}
        label: {type: [string, 'null']}
    Order:
      type: object
      additionalProperties: false
      required:
      - id
      properties:
        id: {type: integer}
        bricklink_order_id: {type: [string, 'null']}
        store: {type: [string, 'null']}
        seller: {type: [string, 'null']}
        date_ordered:
          type: [string, 'null']
          description: ISO-8601 date or date-time, as stored.
        status: {type: [string, 'null']}
        cost:
          type: [string, 'null']
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        currency:
          type: [string, 'null']
          pattern: ^[A-Z]{3,8}$
        phase:
          type: string
          enum: [Draft, Reviewed, Held, Reconciled, Allocated, Counting, Open]
          description: Where the order stands, as the Orders page says it.
        lines: {type: integer, description: Saved lines (lots), not counting a line paired to an earlier one.}
        pieces: {type: integer}
        received: {type: integer}
        allocated: {type: integer}
        held: {type: integer, description: Saved lines on hold.}
    OrderDetail:
      type: object
      additionalProperties: false
      properties:
        order: {$ref: '#/components/schemas/Order'}
        documents:
          type: array
          items: {$ref: '#/components/schemas/OrderDocument'}
        lines:
          type: array
          items: {$ref: '#/components/schemas/OrderLine'}
    OrderReview:
      type: object
      additionalProperties: false
      properties:
        id: {type: integer, description: The saved line.}
        line: {$ref: '#/components/schemas/OrderLine'}
        available: {type: integer, description: Received and not yet allocated.}
        destinations:
          type: array
          items: {$ref: '#/components/schemas/OrderDestination'}
    ListOfOrderReview:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/OrderReview'
        page:
          $ref: '#/components/schemas/PageInfo'
    Allocation:
      type: object
      additionalProperties: false
      required: [id, order_id, line_id, qty, target_type, state]
      properties:
        id: {type: integer}
        confirm_id: {type: string}
        order_id: {type: integer}
        line_id: {type: integer}
        qty: {type: integer}
        state: {type: string, enum: [applied, pending, conflict, undoing, undone]}
        target_type: {type: string, enum: [copy, stock]}
        kind: {type: string, enum: [missing_part, missing_figure, instructions, box, loose_part, loose_figure, loose_other]}
        copy_id: {type: [string, 'null']}
        copy_part_id: {type: [integer, 'null']}
        copy_figure_id: {type: [integer, 'null']}
        stock_id: {type: [string, 'null']}
        item: {$ref: '#/components/schemas/Item'}
        color:
          oneOf:
          - {$ref: '#/components/schemas/Color'}
          - {type: 'null'}
        intent_before: {type: [integer, 'null']}
        intent_after: {type: [integer, 'null']}
        created_at: {type: [string, 'null']}
        applied_at: {type: [string, 'null']}
        undone_at: {type: [string, 'null']}
        target_label: {type: [string, 'null']}
        undo_event_id: {type: [integer, 'null'], description: The save that undoes this allocation, while it is the allocation's own.}
    ListOfAllocation:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Allocation'
        page:
          $ref: '#/components/schemas/PageInfo'
    OrderHistory:
      type: object
      additionalProperties: false
      properties:
        id:
          type: integer
        receipt:
          type: object
          additionalProperties: true
        undone:
          type: boolean
        undo_available:
          type: boolean
        at:
          type: string
        via:
          type: string
        actor:
          type:
          - string
          - 'null'
    ListOfOrderHistory:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/OrderHistory'
        page:
          $ref: '#/components/schemas/PageInfo'
    OrderImport:
      type: object
      properties:
        source:
          type: string
          enum:
          - email
          - xml
          - api
        text:
          type: string
        number:
          type: string
        choice:
          type: string
        label:
          type: string
      required:
      - source
    OrderImportResult:
      type: object
      additionalProperties: false
      properties:
        order_id: {type: integer}
        document_id: {type: integer}
        duplicate: {type: boolean, description: The same document is already there; nothing was written.}
        placed: {type: integer, description: Lines placed on an item.}
        unplaced: {type: integer, description: Lines that wait for hand matching.}
        event_id: {type: [integer, 'null']}
    OrderLineMatch:
      type: object
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The item, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4): a BrickLink colour id with provider bricklink, a Rebrickable colour
            id with rebrickable, a Brick Work colour id when the item is named by id.'
      required:
      - item
    Hold:
      type: object
      properties:
        held:
          type: boolean
      required:
      - held
    OrderPhase:
      type: object
      properties:
        action:
          type: string
          enum:
          - review
          - reopen
          - save
        pairs:
          type: object
          minProperties: 1
          propertyNames:
            pattern: '[0-9]{1,12}'
          additionalProperties:
            type: integer
            minimum: 1
      required:
      - action
      additionalProperties: false
    OrderReceived:
      type: object
      properties:
        counts:
          type: object
          minProperties: 1
          propertyNames:
            pattern: '[0-9]{1,12}'
          additionalProperties:
            type: integer
            minimum: 0
      required:
      - counts
      additionalProperties: false
    OrderAllocate:
      type: object
      properties:
        chosen:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            type: object
            required:
            - line_id
            - target_type
            - quantity
            properties:
              line_id:
                type: integer
                minimum: 1
              target_type:
                enum:
                - copy
                - stock
              quantity:
                type: integer
                minimum: 1
              copy_id:
                type: string
              target:
                enum:
                - part
                - figure
                - instructions
                - box
              target_id:
                type:
                - integer
                - string
              storage_id:
                type:
                - string
                - 'null'
              lot_id:
                type:
                - string
                - 'null'
            additionalProperties: false
            allOf:
            - if:
                properties:
                  target_type:
                    const: copy
              then:
                required:
                - copy_id
                - target
                - target_id
      required:
      - chosen
      additionalProperties: false
    Event:
      type: object
      properties:
        actor:
          type:
          - string
          - 'null'
        id:
          type: integer
        entity:
          type: string
        field:
          type: string
        old_value: {}
        new_value: {}
        at:
          type: string
          format: date-time
        via:
          type: string
          enum:
          - app
          - cli
          - api
          - import
          - migration
        undoable:
          type: boolean
        undone:
          type: boolean
      required:
      - id
      - entity
      - field
      - at
      - via
    UndoResult:
      type: object
      properties:
        undone_event_id:
          type: integer
        event_id:
          type:
          - integer
          - 'null'
        already_undone:
          type: boolean
    Job:
      type: object
      properties:
        id:
          type: integer
        source:
          type: string
        kind:
          type: string
        item:
          oneOf:
          - $ref: '#/components/schemas/Item'
          - type: 'null'
        state:
          type: string
          enum:
          - queued
          - running
          - waiting_for_budget
          - failed
          - done
        attempts:
          type: integer
        retry_at:
          type:
          - string
          - 'null'
          format: date-time
        error:
          type:
          - string
          - 'null'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        steps:
          type: array
          items:
            $ref: '#/components/schemas/JobStep'
        interrupted:
          type: boolean
      required:
      - id
      - state
    JobStep:
      type: object
      properties:
        name:
          type: string
        position:
          type: integer
        state:
          type: string
        source:
          type:
          - string
          - 'null'
        error:
          type:
          - string
          - 'null'
        error_code:
          type:
          - string
          - 'null'
          description: 'Stable code of a failed step: source_not_configured, source_disabled or source_error.'
        retry_at:
          type:
          - string
          - 'null'
          format: date-time
    JobList:
      type: object
      properties:
        jobs:
          type: array
          items:
            $ref: '#/components/schemas/Job'
        skipped:
          type: array
          items:
            type: string
    JobRetry:
      type: object
      additionalProperties: false
      properties:
        step:
          type:
          - string
          - 'null'
    PictureRefresh:
      type: object
      additionalProperties: false
      properties:
        scope:
          type: string
          enum:
          - missing
          - all
          description: missing queues the held items that have a colour with no picture, all every held item.
        kinds:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/Kind'
          description: The item kinds to refresh; all kinds when left out.
        expected_count:
          type:
          - integer
          - 'null'
          description: The number of items the caller saw; the call is refused (422) when the count has changed.
      required:
      - scope
    Source:
      type: object
      properties:
        source:
          type: string
        name:
          type: string
        kind:
          type: string
          enum:
          - api
          - file
          - manual
        enabled:
          type: boolean
        key:
          $ref: '#/components/schemas/KeyState'
        budget:
          type:
          - integer
          - 'null'
        used_today:
          type: integer
        last_success:
          type:
          - string
          - 'null'
          format: date-time
        last_error: {}
      required:
      - source
      - enabled
      - key
    KeyState:
      type: object
      properties:
        configured:
          type: boolean
        origin:
          type:
          - string
          - 'null'
          enum:
          - env
          - stored
          - null
        saved_at:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - configured
      description: Only configured, origin and saved_at. Environment keys win over encrypted stored keys. Key values and fragments are never returned, logged
        or shown. BW_SECRET_KEY is required for key entry.
      additionalProperties: false
    SourceToggle:
      type: object
      properties:
        enabled:
          type: boolean
      required:
      - enabled
    Statistics:
      type: object
      properties:
        completeness: {}
        theme: {}
        storage: {}
        purchase place: {}
    DatabaseCheck:
      type: object
      properties:
        integrity_check:
          type: array
          items:
            type: string
        catalogue_integrity_check:
          type: array
          items:
            type: string
          description: The attached catalogue file's own integrity check; absent without a catalogue.
        foreign_key_check: {}
        row_counts: {}
    Identification:
      type: object
      additionalProperties: false
      required: [id, created_at, has_thumb, candidates]
      properties:
        id: {type: string}
        created_at: {type: [string, 'null']}
        has_thumb: {type: boolean}
        missing_count: {type: [integer, 'null']}
        archived_at: {type: [string, 'null']}
        candidates:
          type: array
          description: The items the photo may show, best first.
          items:
            type: object
            additionalProperties: false
            properties:
              item:
                oneOf:
                - {$ref: '#/components/schemas/Item'}
                - {type: 'null'}
              score: {type: [number, 'null']}
              name: {type: [string, 'null']}
              owned:
                type: [object, 'null']
                additionalProperties: true
                description: 'On the answer of the upload (#45): total held, colours with quantity and storages, needed_by, needed_count and a sentence.'
        unresolved:
          type: array
          description: On the answer of the upload only; predictions that name no item, several, or one still to check.
          items:
            type: object
            additionalProperties: false
            properties:
              kind: {type: string}
              number: {type: string}
              score: {type: [number, 'null']}
              reason: {type: string}
    OneHealth:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Health'
    OneVersion:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Version'
    OneMe:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Me'
    ListOfCatalogueItem:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/CatalogueItem'
        page:
          $ref: '#/components/schemas/PageInfo'
    OneCatalogueItem:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/CatalogueItem'
    OneCatalogueStatus:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/CatalogueStatus'
    ListOfColor:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Color'
        page:
          $ref: '#/components/schemas/PageInfo'
    OneColor:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Color'
    ListOfItem:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Item'
        page:
          $ref: '#/components/schemas/PageInfo'
    OneItemDetail:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/ItemDetail'
    ListOfInventoryLine:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/InventoryLine'
        page:
          $ref: '#/components/schemas/PageInfo'
    ListOfUsedIn:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/UsedIn'
        page:
          $ref: '#/components/schemas/PageInfo'
    ListOfImage:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Image'
        page:
          $ref: '#/components/schemas/PageInfo'
    OneJob:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Job'
    ListOfCopy:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Copy'
        page:
          $ref: '#/components/schemas/PageInfo'
    Created:
      type: object
      properties:
        ids:
          type: array
          items:
            type:
            - string
            - integer
      required:
      - ids
      additionalProperties: false
    WrittenSkipped:
      type: object
      required:
      - data
      - event_id
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/Skipped'
        event_id:
          type: 'null'
        undo_url:
          type: 'null'
        idempotent_replay:
          type: boolean
      additionalProperties: false
    Skipped:
      type: object
      required:
      - skipped
      - existing
      properties:
        skipped:
          type: boolean
          enum:
          - true
        existing:
          $ref: '#/components/schemas/Item'
          description: The item that is already owned or wished.
      additionalProperties: false
    WrittenCreated:
      type: object
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/Created'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
      additionalProperties: false
    WrittenCopy:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Copy'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneCopy:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Copy'
    OneCompleteness:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Completeness'
    WrittenCompleteness:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Completeness'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneCheckState:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/CheckState'
    WrittenCheckState:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/CheckState'
        event_id:
          type:
          - integer
          - 'null'
          description: The receipt of the answer; null when the call changed nothing (a start while the check is running).
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfGap:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Gap'
        page:
          $ref: '#/components/schemas/PageInfo'
    ListOfMatch:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Match'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenReceipt:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Receipt'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfCopyPart:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/CopyPart'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenCopyPart:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/CopyPart'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    WrittenBulkResult:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/BulkResult'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    ListOfCopyFigure:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/CopyFigure'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenCopyFigure:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/CopyFigure'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfStock:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Stock'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenStock:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Stock'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneStock:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Stock'
    ListOfLooseFigurePart:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/LooseFigurePart'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenLooseFigureParts:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/LooseFigureParts'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfMinifigureRow:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/MinifigureRow'
        page:
          $ref: '#/components/schemas/PageInfo'
    ListOfInstructionFile:
      description: The file records (archived ones with `archived=include|only`). `coverage` counts the booklet identities (instructions items) and how many of them have a PDF through the set with their number.
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/InstructionFile'
        page:
          $ref: '#/components/schemas/PageInfo'
        coverage:
          type: object
          properties:
            total:
              type: integer
            covered:
              type: integer
          required:
          - total
          - covered
    OneInstructionFile:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/InstructionFile'
    WrittenInstructionFile:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/InstructionFile'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfPriceCurrent:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PriceCurrent'
        page:
          $ref: '#/components/schemas/PageInfo'
    OneItemPrices:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/ItemPrices'
    ListOfPriceObservation:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/PriceObservation'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenPriceObservation:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/PriceObservation'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfStaleItem:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/StaleItem'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenJobList:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/JobList'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    ListOfWish:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Wish'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenWish:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Wish'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneWish:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Wish'
    ListOfStorage:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Storage'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenStorage:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Storage'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneStorageDetail:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/StorageDetail'
    ListOfLot:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Lot'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenLot:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Lot'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneLotDetail:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/LotDetail'
    ListOfPlace:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Place'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenPlace:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Place'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    WrittenDeleted:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Deleted'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfFlag:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Flag'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenFlag:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Flag'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneRanking:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Ranking'
    ListOfOrder:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Order'
        page:
          $ref: '#/components/schemas/PageInfo'
    OneOrderDetail:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/OrderDetail'
    WrittenOrderImportResult:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/OrderImportResult'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    ListOfEvent:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Event'
        page:
          $ref: '#/components/schemas/PageInfo'
    OneEvent:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Event'
    WrittenUndoResult:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/UndoResult'
        event_id:
          type: integer
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    ListOfJob:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Job'
        page:
          $ref: '#/components/schemas/PageInfo'
    ListOfSource:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Source'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenSource:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Source'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    WrittenCatalogueStatus:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/CatalogueStatus'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    OneSettings:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Settings'
    WrittenSettings:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Settings'
        event_id:
          type:
          - integer
          - 'null'
          description: The event of the change; null when every value sent was the one already stored.
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    OneStatistics:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Statistics'
    OneDatabaseCheck:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/DatabaseCheck'
    ListOfIdentification:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Identification'
        page:
          $ref: '#/components/schemas/PageInfo'
    ListOfToken:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Token'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenTokenCreated:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/TokenCreated'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    WrittenToken:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Token'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    RankingPage:
      type: object
      required:
      - data
      - page
      - settings
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/RankingRow'
        page:
          $ref: '#/components/schemas/PageInfo'
        settings:
          $ref: '#/components/schemas/Settings'
    RankingRow:
      type: object
      properties:
        id:
          type: string
        group:
          type: string
        items: {}
        rank:
          type:
          - integer
          - 'null'
        reasons: {}
        missing_count:
          type: integer
        missing_figures:
          type: integer
        missing_parts:
          type: integer
        original_gap: {}
        stock_used: {}
        unresolved_items: {}
        display_ratio_width: {}
        complete_quote: {}
        listing: {}
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        condition:
          type:
          - string
          - 'null'
          enum:
          - new
          - used
          - null
        completeness:
          type:
          - string
          - 'null'
          enum:
          - sealed
          - complete
          - incomplete
          - null
        completeness_source:
          type:
          - string
          - 'null'
          enum:
          - manual
          - derived
          - null
        storage_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        note:
          type:
          - string
          - 'null'
        current_value:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        current_value_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        pinned:
          type: boolean
        missing:
          type: integer
        damaged:
          type: integer
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
        archived_at:
          type:
          - string
          - 'null'
          format: date-time
        value_when_complete:
          type:
          - string
          - 'null'
        valuation_basis:
          type:
          - string
          - 'null'
        breakdown:
          type: object
          additionalProperties:
            type: string
        repair_cost:
          type:
          - string
          - 'null'
        gross_gain:
          type:
          - string
          - 'null'
        net_gain:
          type:
          - string
          - 'null'
        ratio:
          type:
          - string
          - 'null'
        ratio_width:
          type: number
        ratio_overflow:
          type: boolean
      required:
      - id
      - group
      - items
    WrittenJob:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/Job'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    SyncStatus:
      type: object
      additionalProperties: false
      properties:
        source:
          type: string
        label:
          type: string
        credentials:
          type: object
        link:
          type: object
        last_pull:
          type:
          - object
          - 'null'
        last_send:
          type:
          - object
          - 'null'
        waiting:
          type: integer
    SyncList:
      type: object
      additionalProperties: false
      properties:
        id:
          type: integer
        name:
          type: string
        sets:
          type:
          - integer
          - 'null'
    SyncPlan:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        created_at:
          type: string
        direction:
          type: string
          enum:
          - pull
          - send
        source:
          type: string
        link:
          type: object
        rows:
          type: array
          items:
            type: object
        unmatched:
          type: array
          items:
            type: object
        summary:
          type: object
        note:
          type: string
        remote:
          type: object
          description: What the site holds, as read for this plan.
        state:
          type: object
          description: On a send plan, the baseline the plan was made against.

    SyncApplied:
      type: object
      additionalProperties: false
      properties:
        already_applied:
          type: boolean
        counts:
          type: object
        event_id:
          type:
          - integer
          - 'null'

    SyncSent:
      type: object
      additionalProperties: false
      properties:
        plan:
          type: string
        counts:
          type: object
        rows:
          type: array
          items:
            type: object
        note:
          type: string
    SyncCredentials:
      type: object
      additionalProperties: false
      properties:
        source:
          type: string
        user:
          type: object
        key:
          type: object
    OneSyncStatus:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/SyncStatus'
    SyncListPage:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/SyncList'
    WrittenSyncStatus:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/SyncStatus'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenSyncPlan:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/SyncPlan'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenSyncApplied:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/SyncApplied'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenSyncSent:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/SyncSent'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenSyncCredentials:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/SyncCredentials'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    ExchangeRate:
      type: object
      additionalProperties: false
      properties:
        currency:
          type: string
        per_eur:
          type: string
        as_of:
          type:
          - string
          - 'null'
        source:
          type: string
          enum:
          - manual
          - ecb
    EcbResult:
      type: object
      additionalProperties: false
      properties:
        as_of:
          type: string
        updated:
          type: integer
        kept_manual:
          type: integer
    WrittenExchangeRates:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ExchangeRate'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenEcbResult:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/EcbResult'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenKeyTest:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/KeyTest'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    ImportPlan:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
        created_at:
          type: string
        source:
          type: string
        schema:
          type: object
        fresh:
          type: boolean
        summary:
          type: object
        unplaced:
          type: array
          items:
            type: object
        rows:
          type: array
          items:
            type: object
    ImportApplied:
      type: object
      additionalProperties: false
      properties:
        already_applied:
          type: boolean
        counts:
          type: object
        event_id:
          type:
          - integer
          - 'null'

    WrittenImportPlan:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/ImportPlan'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenImportApplied:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/ImportApplied'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    WrittenIdentification:
      type: object
      additionalProperties: false
      required:
      - data
      - event_id
      - undo_url
      - idempotent_replay
      properties:
        data:
          $ref: '#/components/schemas/Identification'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    KeyTest:
      type: object
      additionalProperties: false
      required:
      - source
      - ok
      - checked_at
      properties:
        source:
          type: string
        ok:
          type: boolean
          const: true
        checked_at:
          type: string
          format: date-time
    SourceKeyInput:
      type: object
      additionalProperties: false
      description: Write-only. One `key` for Rebrickable and Brickset; consumer_key, consumer_secret, token_value and token_secret for BrickLink. Values
        are never returned, logged or shown again.
      properties:
        key:
          type: string
          writeOnly: true
          minLength: 8
          maxLength: 256
        consumer_key:
          type: string
          writeOnly: true
          minLength: 8
          maxLength: 256
        consumer_secret:
          type: string
          writeOnly: true
          minLength: 8
          maxLength: 256
        token_value:
          type: string
          writeOnly: true
          minLength: 8
          maxLength: 256
        token_secret:
          type: string
          writeOnly: true
          minLength: 8
          maxLength: 256
    OneIdentification:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Identification'
    LooseFigureParts:
      type: object
      required:
      - parts
      properties:
        parts:
          type: array
          items:
            $ref: '#/components/schemas/LooseFigurePart'
      additionalProperties: false
    Copy:
      type: object
      properties:
        partout:
          type:
          - object
          - 'null'
          description: 'Part-out value on a single copy read (#38): used quotes for present parts and whole figures.'
          properties:
            value:
              type:
              - string
              - 'null'
            currency:
              type: string
            lines:
              type: integer
            priced:
              type: integer
            unpriced:
              description: Up to 50 lines without a usable quote.
              type: array
              items:
                type: object
                properties:
                  item:
                    $ref: '#/components/schemas/Item'
                  color:
                    oneOf:
                    - $ref: '#/components/schemas/Color'
                    - type: 'null'
            unpriced_count:
              type: integer
        id:
          type: string
        item:
          $ref: '#/components/schemas/Item'
        name:
          type:
          - string
          - 'null'
        condition:
          type:
          - string
          - 'null'
          enum:
          - new
          - used
          - null
        completeness:
          type:
          - string
          - 'null'
          enum:
          - sealed
          - complete
          - incomplete
          - null
        completeness_source:
          type:
          - string
          - 'null'
          enum:
          - manual
          - derived
          - null
        storage_id:
          type:
          - string
          - 'null'
        purchase_location_id:
          type:
          - string
          - 'null'
        purchase_date:
          type:
          - string
          - 'null'
          description: ISO-8601 date or date-time, as stored.
        purchase_price:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        purchase_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        note:
          type:
          - string
          - 'null'
        current_value:
          type:
          - string
          - 'null'
          pattern: ^[0-9]+(\.[0-9]+)?$
          description: Decimal string, never a float.
        current_value_currency:
          type:
          - string
          - 'null'
          pattern: ^[A-Z]{3,8}$
        pinned:
          type: boolean
        flags:
          type: array
          items:
            type: string
        missing:
          type: integer
        damaged:
          type: integer
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
        archived_at:
          type:
          - string
          - 'null'
          format: date-time
        etag:
          type: string
        image_id:
          type:
          - integer
          - 'null'
        inventory:
          $ref: '#/components/schemas/CopyInventory'
      required:
      - id
      - item
    Settings:
      type: object
      properties:
        display_currency:
          type: string
          description: Totals and comparisons across currencies convert into this (#39).
        retail_country:
          type: string
          enum:
          - DE
          - US
          - UK
          - CA
        bricklink_region:
          type: string
        bricklink_currency:
          type: string
          pattern: ^[A-Z]{3,8}$
        incomplete_discount_pct:
          type: number
        source_priority:
          type: object
          description: 'Source order per step and item kind: `{step: {kind or "*": [source ids]}}`, the steps being `pictures` (design 6.8), `metadata` and `market_price`. A step that is sent replaces that step; a step that is left out keeps its order.'
          additionalProperties:
            type: object
            additionalProperties:
              type: array
              items:
                type: string
        import_order: {}
        freshness: {}
        repair: {}
        prefer_bricklink_inventory:
          type: boolean
          description: New copies take BrickLink's part list when one exists (design 4.4).
        candidate_sets_common_max:
          type: integer
          minimum: 25
          description: Lot Detective ignores, by default, the parts that more than this many sets hold (default 300; #200).
    SettingsPatch:
      type: object
      properties:
        display_currency:
          type: string
          description: Totals and comparisons across currencies convert into this (#39).
        retail_country:
          type: string
          enum:
          - DE
          - US
          - UK
          - CA
        bricklink_region:
          type: string
        bricklink_currency:
          type: string
          pattern: ^[A-Z]{3,8}$
        incomplete_discount_pct:
          type: number
        source_priority:
          type: object
          description: 'Source order per step and item kind: `{step: {kind or "*": [source ids]}}`, the steps being `pictures` (design 6.8), `metadata` and `market_price`. A step that is sent replaces that step; a step that is left out keeps its order.'
          additionalProperties:
            type: object
            additionalProperties:
              type: array
              items:
                type: string
        import_order: {}
        freshness: {}
        repair: {}
        prefer_bricklink_inventory:
          type: boolean
          description: New copies take BrickLink's part list when one exists (design 4.4).
        candidate_sets_common_max:
          type: integer
          minimum: 25
          description: Lot Detective ignores, by default, the parts that more than this many sets hold (default 300; #200).
    Problem:
      type: object
      properties:
        type:
          type: string
        title:
          type: string
        status:
          type: integer
        code:
          type: string
          enum:
          - bad_request
          - unknown_filter
          - unauthorized
          - forbidden
          - read_only_instance
          - not_found
          - method_not_allowed
          - api_retired
          - moved
          - archived
          - ambiguous
          - merged
          - conflict
          - stale_match
          - undo_blocked
          - not_undoable
          - idempotency_conflict
          - precondition_failed
          - payload_too_large
          - unsupported_media_type
          - validation_failed
          - unsupported_setting
          - unidentified
          - source_not_configured
          - source_disabled
          - catalogue_not_loaded
          - idempotency_key_required
          - budget_exhausted
          - source_throttled
          - too_many_attempts
          - source_error
          - not_set_up
          - api_disabled
          - db_unavailable
          - internal_error
          - not_implemented
        detail:
          type: string
        instance:
          type: string
        errors:
          type: array
          items:
            $ref: '#/components/schemas/FieldError'
        retry_after:
          type:
          - integer
          - 'null'
        job_id:
          type:
          - integer
          - 'null'
        source:
          type:
          - string
          - 'null'
        candidates:
          type: array
          items:
            $ref: '#/components/schemas/Item'
          description: 'With ambiguous: the items the number names.'
        survivor:
          type: integer
          description: 'With merged and moved: the live item''s id.'
        piece:
          type: string
          description: 'With not_implemented: the piece that brings the operation.'
        error:
          type: string
          description: 'With not_implemented: the same as code.'
      required:
      - type
      - title
      - status
      - code
      description: RFC 9457 problem+json. code is the stable machine key.
    Kind:
      type: string
      enum:
      - set
      - part
      - minifigure
      - instructions
      - box
      - gear
      - book
      - catalog
      description: What the item is (design 3.5); stored words are served (Q8).
    Color:
      type: object
      required:
      - id
      - name
      - rgb
      - bricklink_id
      - rebrickable_id
      properties:
        id:
          type: integer
          description: Brick Work colour id (per install).
        name:
          type: string
        rgb:
          type:
          - string
          - 'null'
          description: Six hex digits.
        bricklink_id:
          type:
          - integer
          - 'null'
        rebrickable_id:
          type:
          - integer
          - 'null'
    ItemBrickLink:
      type: object
      required:
      - type
      - 'no'
      - color_id
      - color_scoped
      - brickwork_color_id
      - preferred
      properties:
        type:
          type: string
          enum:
          - S
          - P
          - M
          - G
          - B
          - C
          - I
          - O
          description: BrickLink item type.
        'no':
          type: string
        color_id:
          type:
          - integer
          - 'null'
          description: The BrickLink colour id the link is scoped to. Null with color_scoped false holds for every colour (design 3.2); null with color_scoped true
            is a link scoped to a colour that has no BrickLink id (see brickwork_color_id), never "every colour".
        color_scoped:
          type: boolean
          description: True when the link holds for one colour only.
        brickwork_color_id:
          type:
          - integer
          - 'null'
          description: The Brick Work colour id the link is scoped to; null when color_scoped is false.
        preferred:
          type: boolean
    Item:
      type: object
      required:
      - id
      - kind
      - name
      - unidentified
      - bricklink
      - rebrickable
      properties:
        id:
          type: integer
          description: 'Brick Work id: per install, not stable across installs (design 3.1).'
        kind:
          $ref: '#/components/schemas/Kind'
        name:
          type: string
        unidentified:
          type: boolean
          description: 'A local item that is not born at Rebrickable: no born key, or a BrickLink-only number (design 3.8). Replaces v1''s `?` type.'
        bricklink:
          type: array
          items:
            $ref: '#/components/schemas/ItemBrickLink'
          description: Confirmed BrickLink links, preferred first; colour-scoped rows list their colour.
        rebrickable:
          oneOf:
          - type: object
            required:
            - key
            properties:
              key:
                type: string
          - type: 'null'
        color:
          allOf:
          - $ref: '#/components/schemas/Color'
          description: 'Only on a by-number or lookup answer given a color: the resolved Brick Work colour.'
    ItemKey:
      type: object
      x-mcp-item: key
      description: 'Names an item in a request: by id, or by provider number (decision 3: the default provider is bricklink). The colour next to it is in
        the same provider space.'
      properties:
        id:
          type: integer
        provider:
          type: string
          enum:
          - bricklink
          - rebrickable
          default: bricklink
        kind:
          $ref: '#/components/schemas/Kind'
        key:
          type: string
      oneOf:
      - required:
        - id
      - required:
        - kind
        - key
    CandidateSetPage:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/CandidateSets'
    CandidateSets:
      type: object
      required:
      - catalogue
      - lot
      - common_max
      - input
      - total
      - limit
      - offset
      - results
      properties:
        catalogue:
          type: object
          description: The index the answer came from.
          required:
          - sets
          - lines
          - postings
          - distinctive_max
          properties:
            sets:
              type: integer
            lines:
              type: integer
            postings:
              type: integer
            distinctive_max:
              type: integer
        lot:
          type: string
        common_max:
          type:
          - integer
          - 'null'
          description: N, the most sets a part may be held by and still count; null when `ignore_common` is false.
        input:
          type: object
          required:
          - lines
          - quantity
          - ignored_common_lines
          - unmatched_lines
          properties:
            lines:
              type: integer
              description: Lines scored (after the common parts were dropped).
            quantity:
              type: integer
            ignored_common_lines:
              type: integer
              description: Lines of the lot dropped because more than N sets hold them.
            unmatched_lines:
              type: integer
              description: Scored lines that no set holds.
        total:
          type: integer
          description: Candidate sets after the filters.
        limit:
          type: integer
        offset:
          type: integer
        results:
          type: array
          items:
            $ref: '#/components/schemas/CandidateSet'
    CandidateSet:
      type: object
      required:
      - rank
      - item
      - picture
      - score
      - evidence
      - coverage
      - reasons
      - covered_lines
      - set_lines
      - distinctive_found
      - distinctive_total
      - flags
      - swaps
      - distinctive_found_parts
      - distinctive_missing_parts
      properties:
        rank:
          type: integer
        item:
          $ref: '#/components/schemas/Item'
        picture:
          oneOf:
          - $ref: '#/components/schemas/CandidatePicture'
          - type: 'null'
        score:
          type: integer
          minimum: 0
          maximum: 100
          description: 'How strongly the found parts point to this set, 0 to 100, relative to the best candidate (evidence over the best candidate''s evidence). Not a probability.'
        evidence:
          type: number
          description: The engine's evidence in nats (ADR 0026).
        coverage:
          type: number
          description: Evidence over the set's total weight, 0 to 1.
        reasons:
          type: array
          items:
            type: string
        covered_quantity:
          type: integer
        set_quantity:
          type: integer
        covered_lines:
          type: integer
        complete_lines:
          type: integer
        set_lines:
          type: integer
        distinctive_found:
          type: integer
        distinctive_total:
          type: integer
        flags:
          type: object
          description: Per flag passed to the engine (`sticker`), what the lines carrying it contributed to this set.
          additionalProperties:
            type: object
            properties:
              lines:
                type: integer
              covered_quantity:
                type: integer
              evidence:
                type: number
        swaps:
          $ref: '#/components/schemas/SetScoreSwaps'
        distinctive_found_parts:
          type: array
          description: Up to 20 distinctive parts the lot has, heaviest first.
          items:
            $ref: '#/components/schemas/CandidatePart'
        distinctive_missing_parts:
          type: array
          description: Up to 20 distinctive parts of the set the lot does not have yet, heaviest first (`quantity` is 0).
          items:
            $ref: '#/components/schemas/CandidatePart'
    CandidatePicture:
      type: object
      required:
      - id
      - content_url
      - image_url
      properties:
        id:
          type:
          - integer
          - 'null'
          description: The newest local picture (`GET /images/{id}/content`).
        content_url:
          type:
          - string
          - 'null'
        image_url:
          type:
          - string
          - 'null'
          description: The catalogue's picture address for the item.
    CandidatePart:
      type: object
      required:
      - item
      - color
      - quantity
      - need
      - weight
      - only_in_set
      - printed
      - picture
      properties:
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        quantity:
          type: integer
          description: How many of it the lot has.
        need:
          type: integer
          description: How many the set holds.
        weight:
          type: number
          description: The line's rarity weight ln(N/df).
        only_in_set:
          type: boolean
          description: Exactly one set holds this part in this colour.
        printed:
          type: boolean
          description: True only for a part that only this set holds and that is printed, that is a part number with a print suffix (`pr` and digits) or the printed child of a type P part relationship.
        picture:
          oneOf:
          - $ref: '#/components/schemas/CandidatePicture'
          - type: 'null'
    StickerCandidatePage:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/StickerCandidates'
    StickerCandidates:
      type: object
      required:
      - lot
      - stock_id
      - item
      - color
      - quantity
      - sticker
      - total
      - limit
      - offset
      - results
      properties:
        lot:
          type: string
        stock_id:
          type: string
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        quantity:
          type: integer
        sticker:
          $ref: '#/components/schemas/StickerState'
        total:
          type: integer
        limit:
          type: integer
        offset:
          type: integer
        results:
          type: array
          items:
            $ref: '#/components/schemas/StickerCandidate'
    StickerState:
      type: object
      required:
      - flagged
      - confirmed
      properties:
        flagged:
          type: boolean
          description: The line holds the Sticker flag.
        confirmed:
          oneOf:
          - $ref: '#/components/schemas/StickerChoice'
          - type: 'null'
          description: The set chosen with "This one", only while the line holds the flag.
    StickerChoice:
      type: object
      required:
      - set_item_id
      - sheet_item_id
      properties:
        set_item_id:
          type: integer
        sheet_item_id:
          type: integer
        set_number:
          type:
          - string
          - 'null'
        set_name:
          type:
          - string
          - 'null'
    StickerCandidate:
      type: object
      required:
      - set
      - sheet
      - year
      - picture
      properties:
        set:
          $ref: '#/components/schemas/Item'
        sheet:
          $ref: '#/components/schemas/Item'
        year:
          type:
          - integer
          - 'null'
        picture:
          oneOf:
          - $ref: '#/components/schemas/CandidatePicture'
          - type: 'null'
          description: The sticker sheet's picture.
    PullListPage:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/PullList'
    PullList:
      type: object
      required:
      - lot
      - set
      - totals
      - nested
      - refusal
      - show
      - total
      - limit
      - offset
      - lines
      properties:
        lot:
          type: object
          required:
          - id
          - name
          properties:
            id:
              type: string
            name:
              type: string
        set:
          $ref: '#/components/schemas/Item'
        totals:
          $ref: '#/components/schemas/PullTotals'
        nested:
          type: boolean
          description: The set is made of other sets; Make it a copy does not handle those yet.
        refusal:
          type:
          - string
          - 'null'
          description: Why Make it a copy would be refused now, or null.
        show:
          type: string
        total:
          type: integer
          description: How many lines `show` keeps.
        limit:
          type: integer
        offset:
          type: integer
        lines:
          type: array
          items:
            $ref: '#/components/schemas/PullLine'
    PullTotals:
      type: object
      required:
      - need
      - held
      - found
      - to_find
      - lines
      - lines_to_find
      - figures_need
      - figures_found
      - lot_pieces
      - moves
      properties:
        need:
          type: integer
          description: Pieces the set has (parts and whole figures).
        held:
          type: integer
          description: Of them, what the lot can give already.
        found:
          type: integer
          description: '`held` plus the pieces ticked in the bulk.'
        to_find:
          type: integer
        lines:
          type: integer
        lines_to_find:
          type: integer
        figures_need:
          type: integer
        figures_found:
          type: integer
        lot_pieces:
          type: integer
          description: Every piece the lot holds, damaged ones included.
        moves:
          type: object
          required:
          - moves
          - missing
          - stays
          properties:
            moves:
              type: integer
              description: Found pieces that would move out of the lot.
            missing:
              type: integer
              description: Pieces recorded as missing on the copy.
            stays:
              type: integer
              description: Pieces the lot would keep (the pieces ticked in the bulk are counted in, then moved).
    PullLine:
      type: object
      required:
      - item
      - color
      - kind
      - category
      - need
      - held
      - found
      - to_find
      - picture
      properties:
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        kind:
          type: string
          enum:
          - part
          - figure
        category:
          type: string
          description: The part's catalogue category (Minifigures for a whole figure).
        need:
          type: integer
        held:
          type: integer
        found:
          type: integer
        to_find:
          type: integer
        picture:
          oneOf:
          - $ref: '#/components/schemas/CandidatePicture'
          - type: 'null'
    PullFound:
      type: object
      description: One line of the pull list and how many of it are found.
      properties:
        item:
          allOf:
          - $ref: '#/components/schemas/ItemKey'
          description: The part or whole minifigure, by number (decision 3) or by id.
        color:
          type:
          - integer
          - 'null'
          description: 'A colour in the provider space of the item key (decision 4); a whole minifigure has none.'
        found:
          type: integer
          minimum: 0
          description: The count found so far, what the lot already holds included.
      required:
      - item
      - found
    PullFoundWritten:
      type: object
      required:
      - line
      - totals
      properties:
        line:
          $ref: '#/components/schemas/PullLine'
        totals:
          $ref: '#/components/schemas/PullTotals'
    WrittenPullFound:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/PullFoundWritten'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    CopyFromLot:
      type: object
      required:
      - copy_id
      - set
      - pieces
      - figures
      - missing_parts
      - missing_figures
      - completeness
      - stays
      properties:
        copy_id:
          type: string
        set:
          $ref: '#/components/schemas/Item'
        pieces:
          type: integer
          description: Parts that moved into the copy.
        figures:
          type: integer
          description: Whole figures that moved into the copy.
        missing_parts:
          type: integer
        missing_figures:
          type: integer
        completeness:
          type: string
          enum:
          - complete
          - incomplete
        stays:
          type: integer
          description: Pieces the lot holds now.
    WrittenCopyFromLot:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/CopyFromLot'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    StickerConfirm:
      type: object
      required:
      - set_item_id
      - sheet_item_id
      properties:
        set_item_id:
          type: integer
          minimum: 1
          description: The set (an item id from the candidates).
        sheet_item_id:
          type: integer
          minimum: 1
          description: Its sticker sheet (an item id from the candidates).
    StickerWritten:
      type: object
      required:
      - changed
      - sticker
      properties:
        changed:
          type: boolean
          description: False when the write was already true and wrote nothing.
        sticker:
          $ref: '#/components/schemas/StickerState'
    WrittenSticker:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/StickerWritten'
        event_id:
          type:
          - integer
          - 'null'
        undo_url:
          type:
          - string
          - 'null'
        idempotent_replay:
          type: boolean
    SetScorePage:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/SetScores'
    SetScores:
      type: object
      required:
      - catalogue
      - source
      - input
      - total
      - limit
      - offset
      - results
      properties:
        catalogue:
          type: object
          description: The index the answer came from.
          required:
          - sets
          - lines
          - postings
          - distinctive_max
          properties:
            sets:
              type: integer
              description: N, the candidate sets (live sets with a latest inventory that has at least one line).
            lines:
              type: integer
              description: Distinct (part, colour) lines and whole figures held by those sets.
            postings:
              type: integer
            distinctive_max:
              type: integer
              description: A line held by at most this many candidate sets is distinctive.
        source:
          type: object
          required:
          - kind
          - id
          properties:
            kind:
              type: string
              enum:
              - lot
              - storage
              - loose
              - stock
            id:
              type:
              - string
              - 'null'
        input:
          type: object
          required:
          - lines
          - quantity
          - matched_lines
          - unmatched_lines
          - unmatched
          properties:
            lines:
              type: integer
            quantity:
              type: integer
            matched_lines:
              type: integer
              description: Lines of the pile that at least one set holds.
            unmatched_lines:
              type: integer
            unmatched:
              type: array
              description: Up to 50 of the lines no set holds.
              items:
                $ref: '#/components/schemas/SetScoreLine'
        total:
          type: integer
          description: Sets that share at least one line with the pile.
        limit:
          type: integer
        offset:
          type: integer
        results:
          type: array
          items:
            $ref: '#/components/schemas/SetScore'
    SetScoreLine:
      type: object
      required:
      - item
      - color
      - quantity
      properties:
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        quantity:
          type: integer
          description: How many of it the pile has.
        need:
          type: integer
          description: How many the set holds (a matched line only).
        covered:
          type: integer
          description: min(quantity, need) (a matched line only).
        weight:
          type: number
          description: The line's rarity weight ln(N/df) (a matched line only).
        flags:
          type: array
          items:
            type: string
    SetScore:
      type: object
      required:
      - rank
      - item
      - evidence
      - coverage
      - covered_quantity
      - set_quantity
      - covered_lines
      - complete_lines
      - set_lines
      - distinctive_found
      - distinctive_total
      - matched
      - flags
      - swaps
      properties:
        rank:
          type: integer
        item:
          $ref: '#/components/schemas/Item'
        evidence:
          type: number
        coverage:
          type: number
        covered_quantity:
          type: integer
        set_quantity:
          type: integer
        covered_lines:
          type: integer
        complete_lines:
          type: integer
          description: Lines the pile covers in full.
        set_lines:
          type: integer
        distinctive_found:
          type: integer
        distinctive_total:
          type: integer
        matched:
          type: array
          items:
            $ref: '#/components/schemas/SetScoreLine'
        flags:
          type: object
          description: Per stock flag name, what the lines carrying it contributed to this set.
          additionalProperties:
            type: object
            required:
            - lines
            - covered_quantity
            - evidence
            properties:
              lines:
                type: integer
              covered_quantity:
                type: integer
              evidence:
                type: number
        swaps:
          $ref: '#/components/schemas/SetScoreSwaps'
    SetScoreSwaps:
      type: object
      description: Listed apart, never in any number above.
      required:
      - lines
      - quantity
      - items
      properties:
        lines:
          type: integer
        quantity:
          type: integer
        items:
          type: array
          description: Up to 20, heaviest first.
          items:
            type: object
            required:
            - kind
            - have
            - wanted
            - quantity
            properties:
              kind:
                type: string
                enum:
                - colour
                - mould
              have:
                $ref: '#/components/schemas/SetScoreLine'
              wanted:
                $ref: '#/components/schemas/SetScoreLine'
              quantity:
                type: integer
    ItemLink:
      type: object
      required:
      - provider
      - type
      - 'no'
      - color_id
      - color_scoped
      - brickwork_color_id
      - status
      - preferred
      properties:
        provider:
          type: string
        type:
          type: string
        'no':
          type: string
        color_id:
          description: The BrickLink colour id the link is scoped to; null for every colour, or for a scope that has no BrickLink colour (see `color_scoped`).
          type:
          - integer
          - 'null'
        color_scoped:
          description: True when the link applies to one colour only.
          type: boolean
        brickwork_color_id:
          description: The scope in Brick Work's own colour space; set exactly when `color_scoped`.
          type:
          - integer
          - 'null'
        status:
          type: string
          enum:
          - matched
          - inferred
          - manual
          - to_check
        method:
          type: string
        origin:
          type: string
          enum:
          - shipped
          - local
          - rule
          - bricklink_list
          - api
          - user
          - migration
        preferred:
          type: boolean
        decided_at:
          type:
          - string
          - 'null'
          format: date-time
    ItemLinkWrite:
      type: object
      required:
      - type
      - 'no'
      additionalProperties: false
      properties:
        provider:
          type: string
          enum:
          - bricklink
          default: bricklink
        type:
          type: string
          enum:
          - S
          - P
          - M
          - G
          - B
          - C
          - I
          - O
        'no':
          type: string
        color_id:
          type:
          - integer
          - 'null'
          description: BrickLink colour id to scope the link to; null for every colour.
        preferred:
          type: boolean
          description: 'Make this the preferred link for its colour scope; the previous one stops being preferred. false means no change to the preference: a preference is replaced by marking another link preferred, never cleared to none (there is always a resolver order).'
    ItemProviderStatus:
      type: object
      required:
      - provider
      - status
      - reason
      properties:
        provider:
          type: string
        status:
          type: string
          enum:
          - unmatched
          - to_check
        reason:
          type: string
          enum:
          - no_match
          - no_candidate
          - kind_differs
          - migration
        evidence: {}
        checked_at:
          type: string
          format: date-time
    LinkRow:
      type: object
      required:
      - item
      properties:
        item:
          $ref: '#/components/schemas/Item'
        link:
          oneOf:
          - $ref: '#/components/schemas/ItemLink'
          - type: 'null'
        provider_status:
          oneOf:
          - $ref: '#/components/schemas/ItemProviderStatus'
          - type: 'null'
      description: Exactly one of link and provider_status is set.
    MergeRequest:
      type: object
      required:
      - survivor
      additionalProperties: false
      properties:
        survivor:
          $ref: '#/components/schemas/ItemKey'
    UnmergeRequest:
      type: object
      additionalProperties: false
      properties:
        merge_id:
          type: integer
          description: The merge to undo; default the latest of this item.
    Merge:
      type: object
      required:
      - merge_id
      - survivor
      - merged
      properties:
        merge_id:
          type: integer
        survivor:
          $ref: '#/components/schemas/Item'
        merged:
          $ref: '#/components/schemas/Item'
        receipt:
          description: What moved and how collisions were resolved (design 3.6).
    BuildScoutPage:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/BuildScout'
    BuildScout:
      type: object
      required:
      - catalogue
      - source
      - input
      - filters
      - sharing
      - total
      - limit
      - offset
      - results
      properties:
        catalogue:
          type: object
          description: The parts index the answer came from, and how many of its sets are made of other sets.
          required:
          - sets
          - lines
          - postings
          - distinctive_max
          - nested
          properties:
            sets:
              type: integer
            lines:
              type: integer
            postings:
              type: integer
            distinctive_max:
              type: integer
            nested:
              type: integer
        source:
          type: object
          required:
          - lots
          - storages
          - loose
          - damaged
          - text
          properties:
            lots:
              type: array
              items:
                type: string
            storages:
              type: array
              items:
                type: string
            loose:
              type: boolean
            damaged:
              type: boolean
            text:
              type: string
              description: The selection in words, 'Loose stock · 2 lots · 3 storages'; 'All loose stock' when none is chosen.
        input:
          type: object
          description: What the chosen stock holds that can be given.
          required:
          - lines
          - pieces
          - figures
          properties:
            lines:
              type: integer
            pieces:
              type: integer
              description: Loose parts counted.
            figures:
              type: integer
              description: Whole loose figures counted.
        filters:
          type: object
          description: The filters the answer applied, null where none.
          additionalProperties: true
        sharing:
          type: integer
          description: Sets that share at least one part line with the stock, before the filters.
        total:
          type: integer
          description: Sets that pass the filters.
        limit:
          type: integer
        offset:
          type: integer
        results:
          type: array
          items:
            $ref: '#/components/schemas/BuildScoutSet'
    BuildScoutSet:
      type: object
      required:
      - rank
      - item
      - year
      - theme
      - parts_available
      - parts_total
      - percent
      - missing_parts
      - missing_lines
      - figures_available
      - figures_required
      - missing_figures
      - nested
      properties:
        rank:
          type: integer
        item:
          $ref: '#/components/schemas/Item'
        year:
          type:
          - integer
          - 'null'
        theme:
          type:
          - string
          - 'null'
        parts_available:
          type: integer
          description: The sum over the set's part lines of min(have, need).
        parts_total:
          type: integer
          description: Pieces of the set's own parts, spares and a minifigure's components left out, the parts of its sub-sets in.
        percent:
          type: number
          description: parts_available over parts_total, in percent to one decimal. Swaps are never in it.
        missing_parts:
          type: integer
          description: parts_total less parts_available, in pieces.
        missing_lines:
          type: integer
          description: Part lines the stock does not cover in full.
        figures_available:
          type: integer
          description: The sum over the set's whole-figure lines of min(have, need) (a loose whole figure counts).
        figures_required:
          type: integer
        missing_figures:
          type: integer
        nested:
          type: boolean
          description: true when the set is made of other sets; Build it does not handle those.
        gaps:
          type: array
          description: With `detail`, the biggest missing part lines.
          items:
            $ref: '#/components/schemas/BuildScoutGap'
        figure_gaps:
          type: array
          description: With `detail`, the whole figures that are missing.
          items:
            $ref: '#/components/schemas/BuildScoutGap'
        cost:
          type: object
          description: With `detail`, the missing parts and figures priced from the current prices.
          required:
          - amount
          - currency
          - priced_lines
          - unpriced_lines
          properties:
            amount:
              type:
              - string
              - 'null'
              description: The sum, two decimals; null when no missing line has a price.
            currency:
              type:
              - string
              - 'null'
            priced_lines:
              type: integer
            unpriced_lines:
              type: integer
        swaps:
          type: object
          description: With `detail`, listed apart and never in any number above (the engine's swaps, ADR 0026).
          required:
          - lines
          - quantity
          - items
          properties:
            lines:
              type: integer
            quantity:
              type: integer
            items:
              type: array
              items:
                type: object
                required:
                - kind
                - have
                - wanted
                - quantity
                properties:
                  kind:
                    type: string
                    enum:
                    - colour
                    - mould
                  have:
                    $ref: '#/components/schemas/SetScoreLine'
                  wanted:
                    $ref: '#/components/schemas/SetScoreLine'
                  quantity:
                    type: integer
    BuildScoutGap:
      type: object
      required:
      - item
      - color
      - need
      - have
      - missing
      properties:
        item:
          $ref: '#/components/schemas/Item'
        color:
          oneOf:
          - $ref: '#/components/schemas/Color'
          - type: 'null'
        need:
          type: integer
        have:
          type: integer
          description: min(stock, need).
        missing:
          type: integer
    BuildFromStockRequest:
      type: object
      additionalProperties: false
      properties:
        lots:
          type: array
          items:
            type: string
          maxItems: 500
          uniqueItems: true
        storages:
          type: array
          items:
            type: string
          maxItems: 500
          uniqueItems: true
        loose:
          type: boolean
        damaged:
          type: boolean
    BuildFromStock:
      type: object
      required:
      - copy_id
      - item
      - pieces
      - figures
      - missing_parts
      - missing_figures
      - completeness
      properties:
        copy_id:
          type: string
        item:
          $ref: '#/components/schemas/Item'
        pieces:
          type: integer
          description: Loose parts moved into the copy.
        figures:
          type: integer
          description: Whole loose figures moved into the copy.
        missing_parts:
          type: integer
          description: Pieces recorded as missing on the copy.
        missing_figures:
          type: integer
        completeness:
          type: string
          enum:
          - complete
          - incomplete
    ChangeVariantRequest:
      type: object
      required:
      - to
      additionalProperties: false
      properties:
        to:
          $ref: '#/components/schemas/ItemKey'
    VariantChange:
      type: object
      required:
      - from
      - to
      - number
      properties:
        from:
          $ref: '#/components/schemas/Item'
        to:
          $ref: '#/components/schemas/Item'
        number:
          type:
          - string
          - 'null'
          description: The BrickLink number that became the new item's preferred link; null when neither item had one to move.
        receipt:
          description: What moved, as `{event_id, counts}`.
    CopyInventory:
      type: object
      required:
      - source
      - version
      - ordinal
      - of
      - pending
      - changed_since_build
      properties:
        source:
          type: string
          enum:
          - rebrickable
          - bricklink
          - rebrickable_api
          - migrated
          - none
        version:
          type:
          - integer
          - 'null'
          description: The Rebrickable inventory version, when the source is rebrickable.
        ordinal:
          type:
          - integer
          - 'null'
          description: Which of the set's lists this is, 1-based, newest last.
        of:
          type: integer
          description: How many lists the set has.
        pending:
          type:
          - string
          - 'null'
          enum:
          - bricklink
          - null
          description: bricklink while a switch waits for its fetch job.
        changed_since_build:
          type: boolean
          description: The catalogue's list for this version changed in a later build.
    CopyInventorySwitch:
      type: object
      required:
      - source
      additionalProperties: false
      properties:
        source:
          type: string
          enum:
          - rebrickable
          - bricklink
        version:
          type: integer
          description: 'With rebrickable: the version; default the latest.'
        remember:
          type: boolean
          description: Also use this list for new copies of the set (the set's part-list preference), in the same event.
    CatalogueStatus:
      type: object
      required:
      - loaded
      properties:
        loaded:
          type: boolean
        items:
          type: integer
        builds:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
              built_at:
                type: string
                format: date-time
              dump_date:
                type:
                - string
                - 'null'
              mapping_version:
                type:
                - string
                - 'null'
              local_mapping_manifest: {}
              bricklink_list: {}
              activated:
                type: boolean
        coverage:
          type: object
          description: Item links per status.
          properties:
            matched:
              type: integer
            inferred:
              type: integer
            manual:
              type: integer
            to_check:
              type: integer
        last_reconcile:
          type:
          - object
          - 'null'
          properties:
            at:
              type: string
              format: date-time
            summary: {}
    OneItem:
      type: object
      required:
      - data
      properties:
        data:
          $ref: '#/components/schemas/Item'
    ListOfItemLink:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ItemLink'
    ListOfItemProviderStatus:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/ItemProviderStatus'
    ListOfLinkRow:
      type: object
      required:
      - data
      - page
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/LinkRow'
        page:
          $ref: '#/components/schemas/PageInfo'
    WrittenItemLink:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/ItemLink'
        event_id:
          type:
          - integer
          - 'null'
          description: The event of the change; null when the link was there as asked (the call is idempotent per link).
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    WrittenBuild:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/BuildFromStock'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    WrittenVariantChange:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/VariantChange'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
    WrittenMerge:
      type: object
      required:
      - data
      - event_id
      properties:
        data:
          $ref: '#/components/schemas/Merge'
        event_id:
          type: integer
        undo_url:
          type: string
        idempotent_replay:
          type: boolean
