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

# Get shipment

> Returns a shipment with its current booking status, tracking numbers and URLs, documents and codes.



## OpenAPI

````yaml /openapi-v2beta.json get /v2/teams/{teamUuid}/shipments/{shipment}
openapi: 3.1.0
info:
  title: Smart Send API
  description: >
    Shipment-centred API for discovering shipping services, booking immutable
    shipments, tracking parcels, downloading business documents, and printing.


    ## Contract status


    This specification describes the target API contract agreed during the API
    design review. It is not a declaration that every operation and behaviour
    has already been deployed. The implementation must be brought into
    conformance before this contract is announced as available.


    ## Endpoint prefixes


    The base URL is `https://api.smartsend.io`. Me, Teams, Service Points,
    Carrier Catalog, Routing, Delivery Options and Shipments use `/v2`.
    Tracking, Booking batches, Shipment Templates, WMS Experimental, Documents
    and Printing use `/beta`. The prefix is part of each endpoint path and the
    resource and pagination URLs returned by the API. Webhooks and batch
    callbacks are delivered to the URL configured by the client.


    ## Shipments and booking


    A shipment represents one logical carrier booking. Integrations own their
    webshop orders and store the returned shipment UUID, tracking numbers,
    documents and drop-off codes on those orders. There is no order
    synchronisation resource and no editing or rebooking of accepted shipment
    input.


    POST /v2/teams/{teamUuid}/shipments validates before persistence and starts
    booking immediately. Upfront validation failure is 422 and creates no
    shipment. A successful booking returns 201. A definitive carrier rejection
    returns 424 with the persisted failed ShipmentResponse. Technical failures
    use appropriate 5xx responses. 424 is the application-specific use of Failed
    Dependency defined by RFC 4918, not a universal carrier convention.


    The server waits up to 10 seconds for the complete booking workflow. If
    processing continues, it returns 202 with ShipmentResponse, Location
    pointing to the ordinary shipment GET, and Retry-After: 5. Follow Location
    with GET. A successful GET always returns 200 with the current
    ShipmentResponse, including while booking is in progress or has failed. The
    response schema is the same; the representation is current, not a frozen
    copy of an earlier HTTP body. The worker's final booking deadline is
    separate from this HTTP wait. A rare late carrier success updates the same
    shipment.


    Booked means the carrier booking has succeeded and all required documents,
    QR codes and drop-off codes are ready. Printing is a separate process and
    does not delay booked. A completed carrier booking must never be repeated to
    recover a document-generation failure. Once the carrier has accepted a
    booking, deletion is forbidden even if document generation subsequently
    fails.


    ## Carrier roles


    Shipment delivery and shipment-specific delivery options expose carrier and
    last_mile_carrier as separate objects, each containing code, name, logo_url
    and icon_url. carrier identifies the provider whose service and account are
    used to book the shipment. service_code continues to identify that carrier's
    service; last_mile_carrier is response data and cannot be selected
    independently in booking input.


    last_mile_carrier is the expected final delivery partner configured for the
    selected shipping route. It is null when unknown. When the booking carrier
    also performs final delivery, return that carrier explicitly in both fields.
    This is planned delivery information, not a confirmation of a physical
    handoff or delivery. Snapshot the expected partner when accepting the
    shipment; later route-configuration changes do not rewrite that shipment's
    attribution. A last-mile partner does not require a separate carrier account
    for the team.


    Last mile follows the physical direction: delivery to the customer for
    outbound shipments, and delivery to the merchant for returns. It does not
    identify the customer's return drop-off network. Carrier branding does not
    change service-point identifiers or tracking numbers and URLs.


    The general GET /v2/teams/{teamUuid}/routes response does not expose
    last_mile_carrier in this version. Its carrier object describes the provider
    whose services the team can book.


    ## Parties, delivery and defaults


    parties.merchant and parties.customer have stable commercial meanings,
    including on returns. When merchant is omitted, use the team's outbound
    sender address or return address as appropriate, falling back to the
    outbound address when no return address is configured. Pickup points,
    selected addons and delivery windows belong to delivery.


    Resolve and snapshot effective booking settings when accepting the shipment,
    including when adding it to an open batch. Later team-setting changes do not
    mutate accepted shipments. This contract has no per-booking overrides of
    team document or automatic-print preferences. Ordered team format
    preferences are negotiated up front; reject an incompatible selection with
    422 rather than silently choosing an unaccepted format. Carrier-specific
    constraints can still cause a subsequent booking failure.


    ## Currency and measurement units


    In requests and responses, each monetary amount is an object such as
    `{"value": 3920, "currency": "DKK"}`. The integer value uses the currency's
    minor unit: this example means DKK 39.20. Each weight is an object such as
    `{"value": 1500, "unit": "g"}`, and each length is an object such as
    `{"value": 30, "unit": "cm"}`. There are no shared currency or unit fields
    on the shipment.


    Each supplied object requires both fields. Currency and units never fall
    back to team defaults. Optional amounts or measurements may be omitted or
    null where the field allows it; null means unknown, not zero. A partial
    object such as `{"value": 1500}` is invalid.


    Within one shipment, all non-null monetary amounts must use the same
    currency, all parcel, item and dangerous-goods weights must use the same
    weight unit, and all parcel lengths, widths and heights must use the same
    dimension unit. This also applies to delivery-options input and templates,
    including the final merged request. Responses preserve the accepted
    currencies and units. Different shipments in a batch or list may use
    different currencies and units.


    Missing or invalid object fields and mixed currencies or units return 422
    with the affected field paths. Upfront shipment validation creates no
    shipment, and batch-add validation adds none of that request.


    Document dimensions and printer paper sizes use millimetres, independently
    of parcel dimensions. Service-point proximity results use the same
    value/unit structure in metres; distance is returned only by the closest
    search.


    ## Documents and codes


    Document means a completed business document intended for viewing or
    printing, such as a label, customs declaration, report or end-of-day
    manifest. Documents are team resources and may be associated with shipments,
    reports or manifests. QR images and machine-readable data exports are not
    Document resources.


    Shipment.documents embeds its booking documents, including metadata and
    expiring download URLs, never base64 file data. A document may cover
    multiple parcels or multiple document types. qr_codes and drop_off_codes are
    separate arrays directly on Shipment. A shared QR code is one array entry.
    Where a carrier returns one code per parcel, array index n corresponds to
    parcels[n]; no explicit parcel relation is exposed for these codes. Parcel
    and code order remains stable across responses.


    GET and idempotent replay can refresh file URLs without rebooking,
    generating documents again, or submitting print jobs. Access to an expired
    URL is recovered by retrieving the owning resource again.


    ## Documents, printers and print jobs


    Document represents one completed file. Shipment responses embed document
    metadata without source; document list/detail endpoints include source.
    width and height are distance objects in millimetres at document level;
    page_count is the number of pages or labels in the file. Every page or label
    must have the same dimensions in its finished orientation. For example,
    101.6 × 152.4 mm labels and an A4 invoice are separate documents with
    separate files. A document can contain multiple pages of the same size.
    Dimensions and page_count are null when unknown or not applicable, such as
    an XLSX report without fixed pagination. Null must not be used to disguise
    mixed page sizes. Store dimensions and page count when producing the file so
    metadata reads do not fetch or parse file contents.


    Document.print_status exposes the progress of the most recently created
    local print attempt directly in document and shipment responses. A null
    print_status means no local print request exists; the field is still
    present. Null does not mean an unknown outcome. pending means the request is
    recorded and Smart Send is preparing or waiting to submit it; queued means
    the print service has accepted it; printing means the provider reports
    processing; printed means the best available successful completion
    acknowledgement; failed means a known failure; unknown means the current
    outcome cannot be established. These attempt states have the same meanings
    as PrintJob.state. Printed currently means delivery to the operating-system
    print queue. Printing a downloaded file outside Smart Send is not observed.


    Select the most recently created print attempt by creation time and a stable
    creation-order tie-breaker, not by updated_at or callback arrival time. A
    new reprint immediately becomes the attempt represented by print_status,
    even after an earlier print succeeded. For example, printed can become
    pending and then failed. Delayed updates to older jobs update their own
    history without overriding the newer attempt's status.


    Retrieve all print attempts separately with GET
    /beta/teams/{teamUuid}/print-jobs?document_uuid=... and follow the cursor
    until the end. Each PrintJob contains its state, fixed printer identity,
    copy count and timestamps. Earlier successful attempts remain in the history
    after a later failure. Document.updated_at advances when its published
    print_status or other document metadata changes; each job has its own
    updated_at. Print updates do not advance Shipment.updated_at or change its
    booking or tracking state. On a thin print_job.updated webhook, use
    document_uuid to retrieve the current document; the notification may concern
    an older attempt.


    Printer is current team configuration: identity, display name, availability,
    supported formats and paper_sizes. paper_sizes is null when unknown,
    otherwise an array of driver-advertised named sizes with width and height
    distance objects in millimetres. Individual dimensions are null when only
    the name is known. An empty array means the provider reported no named
    sizes, not that printing or custom sizes are unsupported. Multiple sizes may
    be advertised at once. This list does not map sizes to trays or confirm
    which paper is currently loaded. GET
    /beta/teams/{teamUuid}/printers/{printer} returns that current resource.
    Default selection rules are part of team settings and may choose different
    printers for different file formats and page layouts. Print jobs embed only
    the selected printer identity captured for the attempt, so later renames,
    availability changes or removal do not rewrite history. They also embed the
    document identity and display metadata captured when the job was created;
    current document metadata is retrieved through the document endpoint.


    One PrintJob represents one logical print attempt for an entire completed
    file and a copy count. All print attempts use the same public
    representation, regardless of how they were initiated. Record accepted print
    intent locally before file preparation or external submission; setup failure
    then produces a failed job rather than disappearing. When booking also
    requests printing, record the corresponding local jobs before returning
    document metadata so the response shows pending, or a later state if already
    reached. Printing itself remains asynchronous. printer may be null if an
    accepted attempt has not selected a target or failed before selection. Once
    selected, the target is fixed for the attempt. POST
    /beta/teams/{teamUuid}/print-jobs validates its target before accepting a
    job and returns 422 when invalid. Rejected requests create no print attempt
    and do not change the document's current print_status.


    POST /beta/teams/{teamUuid}/print-jobs returns 201 once the local job is
    durably accepted, normally pending. Printing continues asynchronously;
    retrieve Location or consume print_job.updated notifications. POST and GET
    return the same PrintJobResponse structure. queued means accepted by the
    print service; printed requires its best available completion
    acknowledgement, currently delivery to the operating-system print queue.
    Printing is independent of document readiness and shipment booking state.
    Duplicate or delayed provider updates must not erase a confirmed success; a
    subsequent successful acknowledgement clears a previous failure on the same
    job. Reprints create separate jobs, and unknown outcomes must be checked
    before requesting another print to avoid duplicate output.


    ## Idempotency


    Idempotency-Key is optional on operations that declare it. Without a key,
    each valid create request is independent, even for identical content. No key
    is generated from the payload. Use a fresh client-generated key for each
    intended action and reuse it for recovery after a lost response.


    Keys are scoped to the team, HTTP method and canonical target path. A key
    binds atomically to the accepted action and its resources, with a request
    fingerprint. Object-key ordering is ignored; array order is significant.
    Resolve defaults only once for the accepted action. A changed payload with
    the same key is 422 with a validation error for Idempotency-Key. A
    concurrent duplicate is 409 with Retry-After and, when known, Location. Once
    completed, reconstruct the result from the stored outcome and current
    resource representation and return Idempotency-Replayed: true. URLs and
    subsequent resource state can therefore differ from the first response. For
    shipment creation, the status reflects the booking outcome: 201 for success
    or 424 for carrier rejection, even if a later cancellation has changed the
    current shipment state.


    Retain keys for at least 24 hours from acceptance and never expire an
    actively processing action. After expiry, reusing a key may execute a new
    action. Authentication, authorisation and upfront validation failures do not
    reserve a key. The header does not replace the 202/Location polling flow.
    Idempotency-Replayed is this API's documented extension, not a standard HTTP
    header.


    ## HTTP errors


    Request errors use JSON: message for an ordinary error, with an additional
    errors object for 422 validation failures. There is no custom error code
    field. Use the HTTP status, documented response headers and resource state
    to decide what to do; message text may be localised and can change. Send
    Accept: application/json.


    | Status | Meaning | Client action |

    | --- | --- | --- |

    | 401 | Missing or invalid authentication. | Supply valid credentials. |

    | 403 | Missing permission or scope. | Check team access and permissions. |

    | 404 | Resource unavailable to this team. | Check the resource identifier
    and team. |

    | 409 with Retry-After | An action with this idempotency key is still
    processing. | Wait, then GET Location if supplied; otherwise retry the
    original request with the same key and payload. |

    | 409 without Retry-After | Conflict with resource state or an ambiguous
    tracking lookup. | Retrieve current state or supply the documented tracking
    filters. Do not automatically repeat an unchanged request. |

    | 410 | Tracking cursor expired. | Resynchronise and establish a new feed
    position. |

    | 422 | Invalid input, including reuse of a key with different input. |
    Correct the entries in errors. Upfront booking validation creates no
    shipment; batch-add validation adds none of that request. |

    | 424 | Carrier rejected an accepted booking. | Inspect the persisted failed
    ShipmentResponse. Corrected input requires a new shipment. |

    | 429 | Rate limit reached. | Wait for Retry-After. |

    | 500 | Unexpected server failure. | Recover using the known resource URL or
    original idempotency key; include Request-ID in support reports. |

    | 502 | Accepted booking workflow failed technically. | Inspect the failed
    ShipmentResponse; recover documents without rebooking after carrier
    acceptance. |

    | 503 | Temporary service unavailability. | Wait for Retry-After; preserve
    the original idempotency key when retrying an action. |

    | 504 | Final booking deadline expired. | Inspect the persisted failed
    ShipmentResponse; a rare late carrier success may still update it. |


    The distinction between the two 409 cases using Retry-After is this API's
    convention, not a universal HTTP rule. The usual 10-second booking wait
    returns 202, not 504. A later GET returns 200 when retrieval succeeds, even
    when the shipment's state is failed. Booking-specific 424/502/504 responses
    keep the ShipmentResponse shape rather than switching to a generic
    message-only body.


    ### Invalid shipment input


    ```http

    HTTP/1.1 422 Unprocessable Content

    Content-Type: application/json

    Request-ID: req-example-validation


    {
      "message": "The customer postal code is required.",
      "errors": {
        "parties.customer.address.postal_code": [
          "The customer postal code is required."
        ]
      }
    }

    ```


    ### Batch membership is locked


    ```http

    HTTP/1.1 409 Conflict

    Content-Type: application/json

    Request-ID: req-example-batch


    {
      "message": "Shipments can only be added to an open batch."
    }

    ```


    ### An idempotent request is still processing


    ```http

    HTTP/1.1 409 Conflict

    Content-Type: application/json

    Retry-After: 5

    Request-ID: req-example-processing


    {
      "message": "A request with this Idempotency-Key is still being processed."
    }

    ```


    Location may additionally identify the resource when known. Browser clients
    must be able to read Location, Retry-After, Request-ID and
    Idempotency-Replayed on cross-origin responses; the server exposes these
    through Access-Control-Expose-Headers.


    ## Pagination and synchronisation


    Paginated requests use cursor and per_page for cursor pagination, or page
    and per_page for page pagination. Omit cursor or page for the first page.
    Page numbers start at 1; cursors are opaque. Page-size defaults and limits
    are declared for each endpoint.


    All paginated responses contain data, links and meta. links always contains
    first, last, prev and next. Cursor pagination sets first and last to null;
    its meta contains path, per_page, next_cursor and prev_cursor. Page
    pagination provides first/last URLs and meta.current_page, from, last_page,
    path, per_page, to and total. Pagination links appear only in the top-level
    links object. An empty page has an empty data array and null from/to.
    meta.path is the collection URL without query parameters.


    Follow the returned navigation URLs with GET. They preserve filters,
    sorting, per_page and the fixed sync boundary where applicable. Changing
    these values starts a new page sequence. Shipments add meta.sync_until and
    tracking adds meta.resume_cursor as endpoint-specific extensions. Cursor
    pagination does not provide a total count or last page number.


    Shipment lists represent current resources, not every intermediate change.
    Shipment.updated_at follows its booking lifecycle, including cancellation;
    tracking changes, print updates and refreshed file URLs do not advance it.
    For incremental sync use inclusive updated_since, sort=updated_at and the
    server-provided sync_until boundary. Follow all next links, then persist
    that boundary. On the next round, subtract an overlap (60 seconds is a
    suggested starting point) and upsert by shipment UUID. Mutable timestamps
    can cause duplicates or omit intermediate states; overlap does not turn this
    into a lossless history. Deleted shipments are excluded from lists.
    Incremental polling does not report deletions; consume shipment.deleted
    webhooks or periodically reconcile the full shipment list.


    The dedicated tracking/events endpoint is append-only and uses publication
    order, not carrier event time. Its resume_cursor remains usable at the end
    of a page sequence, including empty responses. ETA changes also produce feed
    entries. Tracking and print resources have their own timestamps.


    ## Webhooks and batch callbacks


    Team webhooks are configured through team settings. A batch may additionally
    register its own callback during creation. Both use the same signed thin
    event envelopes: event id, type, occurred_at, team_uuid and affected
    resource identifiers. Retrieve full resource data through the ordinary
    authenticated API when needed. A GET returns current state, which can differ
    from the state when the event occurred. Tracking notifications wake the
    consumer to resume the tracking event feed; deletion notifications identify
    what to remove without requiring a successful GET. Full payloads may be
    added later as an explicit opt-in. Delivery can be duplicated or arrive out
    of order; deduplicate by event id and retrieve the current resource when
    needed. A callback failure never repeats a booking or print action.
    Signatures follow the Standard Webhooks convention. See the callback and
    webhook definitions for delivery and acknowledgement rules.


    ## Localisation and request identification


    Accept-Language takes precedence over the team's default language, with
    English as fallback. Carrier, service and addon codes are stable; names and
    messages may be localised. Error messages are for people, not client control
    flow. A descriptive User-Agent identifies the integration. Request-ID is
    returned on every API response and should be included in support reports.
    Currency amounts use the ISO 4217 currency's minor unit; null means unknown,
    not zero. Dates use RFC 3339 with an explicit UTC offset.
  version: 2.0.0-beta
  contact:
    name: Smart Send
    url: https://www.smartsend.io
  x-contract-status: design
  x-design-defaults:
    http_wait_seconds: 10
    poll_after_seconds: 5
    idempotency_retention_hours: 24
    list_default_per_page: 100
    list_max_per_page: 1000
    batch_add_max_shipments: 100
    webhook_retry_window_hours: 24
    tracking_feed_retention_days: 90
  x-webhook-payload-mode: thin
servers:
  - url: https://api.smartsend.io
    description: Production
security:
  - bearerAuth: []
  - oauth2: []
tags:
  - name: Me
    description: Information about the authenticated user
  - name: Teams
    description: Teams available to the authenticated user
  - name: Service Points
    description: Pickup points and delivery locations
  - name: Carrier Catalog
    description: >-
      Global reference data for carriers, services, and addons. Not
      team-specific.
  - name: Routing
    description: >-
      Team-specific listing of available carriers, services, and addons based on
      configured carrier accounts. Pre-shipment meaning no shipment details
      required.
  - name: Delivery Options
    description: >-
      Shipment-specific delivery options including available services, addons,
      estimated pricing, and delivery windows.
  - name: Tracking
    description: Shipment tracking information and event history
  - name: Shipments
    description: >-
      Immutable booking input, one logical booking per shipment, cancellation
      and synchronisation.
  - name: Booking batches
    description: >-
      Validate shipments before adding them to a batch; after start, book one
      shipment at a time in insertion order.
    externalDocs:
      description: Batch booking documentation
      url: https://docs.smartsend.io/features/booking#batch-booking
  - name: Shipment Templates
    description: >-
      Reusable shipment templates for quickly creating shipments with
      pre-configured delivery, consignment, and parcel settings.
  - name: WMS Experimental
    description: >-
      Warehouse management for a team's configured WMS driver. Covers
      fulfillment requests (listing open requests, inspecting picking lines,
      recording packed lines), inventory levels (listing, moving between bins,
      adjusting counts), and catalog items (SKU lookup).
  - name: Documents
    description: >-
      Completed business documents for viewing or printing, with metadata and
      download links.
  - name: Printing
    description: Discover printers and follow document print jobs.
  - name: Webhooks
    description: Signed resource updates and batch-specific callbacks.
paths:
  /v2/teams/{teamUuid}/shipments/{shipment}:
    get:
      tags:
        - Shipments
      summary: Get shipment
      description: >-
        Returns a shipment with its current booking status, tracking numbers and
        URLs, documents and codes.
      operationId: getShipment
      parameters:
        - $ref: '#/components/parameters/teamUuid'
        - $ref: '#/components/parameters/Accept-Language'
        - $ref: '#/components/parameters/Request-ID'
        - name: shipment
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: UUID of the shipment in this team.
      responses:
        '200':
          description: Current shipment state and results.
          headers:
            Request-ID:
              $ref: '#/components/headers/Request-ID'
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            Cache-Control:
              $ref: '#/components/headers/Cache-Control'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ShipmentResponse'
              examples:
                Full:
                  $ref: '#/components/examples/BookedShipment'
        '401':
          $ref: '#/components/responses/ApiUnauthorized'
        '403':
          $ref: '#/components/responses/ApiForbidden'
        '404':
          $ref: '#/components/responses/ApiNotFound'
        '422':
          $ref: '#/components/responses/ApiValidationError'
        '429':
          $ref: '#/components/responses/ApiTooManyRequests'
        '500':
          $ref: '#/components/responses/ApiInternalServerError'
        '503':
          $ref: '#/components/responses/ApiServiceUnavailable'
      security:
        - bearerAuth: []
        - oauth2:
            - shipment:read
components:
  parameters:
    teamUuid:
      name: teamUuid
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: Team uuid. All resources are scoped to this team.
    Accept-Language:
      name: Accept-Language
      in: header
      required: false
      schema:
        type: string
        default: en
        examples:
          - da-DK, da;q=0.9, en;q=0.8
      description: >-
        Preferred language(s) for translatable content using BCP 47 language
        tags. Supports quality values (q-factors) for priority ordering. The API
        negotiates the best available language based on this header, the team's
        configured language, and available translations. If omitted, the team's
        default language is used.
    Request-ID:
      name: Request-ID
      in: header
      required: false
      schema:
        type: string
        minLength: 1
        maxLength: 64
        pattern: ^[A-Za-z0-9._-]{1,64}$
      description: >-
        Optional client-supplied request identifier. When provided and matching
        the validation pattern, the value is echoed back in the `Request-ID`
        response header. Otherwise the server generates one. Use this to
        correlate requests between client and server when reporting issues.
      examples:
        uuid:
          summary: UUID v7
          value: 019c486f-c237-76f5-85e1-ba7017a77024
        opaque:
          summary: Opaque client-generated key
          value: booking-12345-at-1768609378
  headers:
    Request-ID:
      description: >-
        Unique identifier for this HTTP request. Always present in responses.
        Echoes the client-supplied `Request-ID` request header when it matches
        the validation pattern; otherwise the server generates a UUIDv7. Include
        this value when reporting issues so support can locate the request in
        logs.
      schema:
        type: string
        minLength: 1
        maxLength: 64
        pattern: ^[A-Za-z0-9._-]{1,64}$
    Retry-After:
      description: >-
        Delay in seconds before the next polling or retry request. Booking
        polling normally uses 5.
      schema:
        type: integer
        minimum: 1
        examples:
          - 5
    Cache-Control:
      description: >-
        Shipment, document, tracking and print responses contain private data
        and expiring URLs.
      schema:
        type: string
        const: private, no-store
  schemas:
    ShipmentResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Shipment'
      required:
        - data
    Shipment:
      type: object
      properties:
        uuid:
          type: string
          description: Resource UUID.
          format: uuid
          examples:
            - 22222222-2222-4222-8222-222222222222
        state:
          $ref: '#/components/schemas/ShipmentState'
        invoice_number:
          type:
            - 'null'
            - string
          description: >-
            Customs invoice number when applicable. Use reference for the public
            order reference.
          examples:
            - INV-1001121
        reference:
          type:
            - 'null'
            - string
          description: >-
            Public reference, e.g. order number or SKU, which may be forwarded
            to the carrier or printed. Not necessarily unique.
          examples:
            - Order-5521
        identifier:
          type:
            - 'null'
            - string
          description: >-
            Private integration reference, e.g. a database ID. Not used for
            deduplication and not forwarded to carrier labels. Not necessarily
            unique.
          examples:
            - shop-order-1042
        uri:
          type:
            - 'null'
            - string
          format: uri
          description: >-
            URI linking to the source of this shipment (webshop order URL, deep
            link, or any URI scheme)
          examples:
            - https://shop.example.com/admin/orders/1042
        delivery:
          $ref: '#/components/schemas/DeliveryInfo'
        parties:
          $ref: '#/components/schemas/ShipmentParties'
        parcels:
          type: array
          items:
            $ref: '#/components/schemas/ShipmentParcel'
          description: Stable accepted parcel order.
          minItems: 1
        total_net_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Total goods value excluding tax.
          examples:
            - value: 15920
              currency: DKK
        tax_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Total goods tax.
          examples:
            - value: 3980
              currency: DKK
        duty_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Total goods duty.
          examples:
            - value: 5572
              currency: DKK
        shipping_net_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Shipping cost excluding tax.
          examples:
            - value: 3920
              currency: DKK
        shipping_tax_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Shipping tax.
          examples:
            - value: 980
              currency: DKK
        content_type:
          anyOf:
            - $ref: '#/components/schemas/ShipmentContentType'
            - type: 'null'
          examples:
            - commercial_goods
        documents:
          type: array
          items:
            $ref: '#/components/schemas/ShipmentDocument'
          description: >-
            Booking documents with metadata and download links. The enclosing
            shipment supplies the source, so source is omitted. Empty when no
            documents are required. Never base64. Required documents are ready
            before state becomes booked.
        qr_codes:
          type: array
          items:
            $ref: '#/components/schemas/QrCode'
          description: >-
            Shipment-level QR images. One entry may apply to the whole shipment.
            Where one QR is supplied per parcel, index n corresponds to
            parcels[n]; this is an ordering convention, not a relation.
        drop_off_codes:
          type: array
          items:
            type: string
            description: >-
              Text code to present or write when handing in a parcel. Preserve
              leading zeroes.
            minLength: 1
          description: >-
            Shipment-level drop-off codes. When supplied one per parcel, index n
            corresponds to parcels[n]. No parcel UUID links are exposed.
        created_at:
          type: string
          format: date-time
          description: When immutable shipment input was accepted.
          examples:
            - '2026-09-16T10:00:00Z'
        updated_at:
          type: string
          format: date-time
          description: >-
            When shipment lifecycle state/result changed. Excludes tracking,
            print updates and URL refreshes.
          examples:
            - '2026-09-16T10:00:02Z'
        booked_at:
          type:
            - string
            - 'null'
          format: date-time
          description: >-
            First time the carrier booking and all required documents/codes were
            ready. Retained after cancellation.
          examples:
            - '2026-09-16T10:00:02Z'
        cancelled_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When cancellation became effective internally.
        voided_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When carrier cancellation was confirmed.
      required:
        - uuid
        - state
        - invoice_number
        - reference
        - identifier
        - uri
        - delivery
        - parties
        - parcels
        - total_net_amount
        - tax_amount
        - duty_amount
        - shipping_net_amount
        - shipping_tax_amount
        - content_type
        - documents
        - qr_codes
        - drop_off_codes
        - created_at
        - updated_at
        - booked_at
        - cancelled_at
        - voided_at
      description: >-
        Current immutable booking input plus evolving lifecycle and results.
        Each shipment has one logical booking. Full event and print histories
        are retrieved through their own paginated endpoints. A failed document
        workflow may still have a carrier booking; never blindly rebook such a
        result. Amounts and measurements include their own currency or unit,
        preserved from the accepted input. All shipment, parcel and item amounts
        share one currency; all weights, including dangerous goods, share one
        unit; all parcel dimensions share one unit. Document dimensions are
        independent.
    ApiErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: >-
            Human-readable, possibly localised explanation. Do not parse this
            text for client control flow.
      required:
        - message
      description: >-
        An unsuccessful API request, using JSON with message and no custom error
        code. Persisted booking outcomes use ShipmentResponse where documented.
    ApiValidationErrorResponse:
      type: object
      properties:
        message:
          type: string
          description: >-
            Human-readable, possibly localised explanation. Do not parse this
            text for client control flow.
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          description: >-
            Field or header names mapped to validation messages. Nested input
            uses dot notation, e.g. data.0.parties.customer.address.country.
            Header validation uses the header name, e.g. Idempotency-Key.
      required:
        - message
        - errors
      description: >-
        422 validation response. Field errors use dot notation for nested input;
        Idempotency-Key identifies a header validation error.
    ShipmentState:
      type: string
      enum:
        - pending
        - queued
        - booking
        - booked
        - failed
        - cancelling
        - cancelled
        - voided
      description: >-
        Booking state:


        - `pending`: Accepted in an open batch.

        - `queued`: Waiting to start booking.

        - `booking`: The carrier/document/code workflow is running.

        - `booked`: The carrier has accepted the booking and all required
        documents/codes are ready.

        - `failed`: The workflow failed or reached its final deadline.

        - `cancelling`: Cancellation is running.

        - `cancelled`: Cancelled internally without confirmed carrier
        cancellation; also used for unstarted batch members stopped before
        booking.

        - `voided`: Cancelled internally and confirmed cancelled by the carrier.


        A rare late success may change `failed` to `booked` or `cancelled` to
        `voided`. Delivery status belongs to tracking.
    DeliveryInfo:
      type: object
      properties:
        carrier:
          $ref: '#/components/schemas/CarrierSummary'
          description: >-
            Carrier whose service and account are used for booking. Its code
            identifies the carrier part of service_code.
        last_mile_carrier:
          anyOf:
            - $ref: '#/components/schemas/CarrierSummary'
            - type: 'null'
          description: >-
            Expected final delivery partner from the selected shipping route.
            Null means unknown. If carrier also performs final delivery, return
            the same carrier identity here explicitly. For returns, final
            delivery is to the merchant. This field does not identify the
            tracking provider or the return drop-off network. The expected
            partner is snapshotted at shipment acceptance; later route changes
            do not alter it.
        service_code:
          type: string
          description: >-
            Full service code (carrier.code + '_' + service suffix). It remains
            tied to the booking carrier, including when another carrier performs
            final delivery.
          examples:
            - postnord_agent
        service_name:
          type: string
          description: Localized human-readable service name
          examples:
            - Pickup Point
        is_pickup:
          type: boolean
          description: Whether this service delivers to pickup points
          examples:
            - true
        is_return:
          type: boolean
          description: Whether this is a return service
          examples:
            - false
        addons:
          type: array
          items:
            $ref: '#/components/schemas/Addon'
          description: Effective selected addons, including their display names.
        pickup_point:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/PickupPoint'
          examples:
            - uuid: 99999999-9999-4999-8999-999999999999
              code: '12345'
              name: Example Parcel Shop
              address:
                address_lines:
                  - Eksempelvej 20
                postal_code: '8000'
                city: Aarhus C
                country: DK
                administrative_area: '82'
          description: >-
            Selected pickup point, or null when none is selected or applicable.
            An empty object is not a valid pickup point.
        delivery_window:
          anyOf:
            - $ref: '#/components/schemas/DateTimeWindow'
            - type: 'null'
        incoterm:
          anyOf:
            - $ref: '#/components/schemas/Incoterm'
            - type: 'null'
          examples:
            - DAP
      required:
        - carrier
        - last_mile_carrier
        - service_code
        - service_name
        - is_pickup
        - is_return
        - addons
        - pickup_point
        - delivery_window
        - incoterm
      description: >-
        Resolved delivery input with the booking carrier, expected last-mile
        partner, service and addon names. Required booking choices and expected
        carrier identities are frozen at acceptance.
    ShipmentParties:
      type: object
      properties:
        merchant:
          $ref: '#/components/schemas/MerchantParty'
        customer:
          $ref: '#/components/schemas/CustomerParty'
      required:
        - merchant
        - customer
      description: Resolved, direction-stable parties snapshotted at acceptance.
    ShipmentParcel:
      type: object
      properties:
        uuid:
          type: string
          description: Stable parcel UUID.
          format: uuid
          examples:
            - 33333333-3333-4333-8333-333333333333
        reference:
          type:
            - 'null'
            - string
          description: >-
            Public reference, e.g. order number or SKU, which may be forwarded
            to the carrier or printed. Not necessarily unique.
          examples:
            - ORDER-1042-1
        identifier:
          type:
            - 'null'
            - string
          description: >-
            Private integration reference, e.g. a database ID. Not used for
            deduplication and not forwarded to carrier labels. Not necessarily
            unique.
          examples:
            - shop-parcel-1
        freetext:
          type:
            - 'null'
            - string
          description: Description or notes for the parcel
          examples:
            - Gift wrapped as per requested
        gross_weight:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/Weight'
          description: Weight of the parcel including packaging and contents.
          examples:
            - value: 1500
              unit: g
        length:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/Distance'
          description: Parcel length.
          examples:
            - value: 30
              unit: cm
        width:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/Distance'
          description: Parcel width.
          examples:
            - value: 20
              unit: cm
        height:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/Distance'
          description: Parcel height.
          examples:
            - value: 15
              unit: cm
        total_net_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Total value excluding tax.
          examples:
            - value: 15920
              currency: DKK
        tax_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Tax amount.
          examples:
            - value: 3980
              currency: DKK
        duty_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Duty amount.
          examples:
            - value: 5572
              currency: DKK
        items:
          type: array
          items:
            $ref: '#/components/schemas/ShipmentParcelItem'
        tracking_number:
          type:
            - string
            - 'null'
          description: Carrier tracking number; preserve leading zeroes.
          examples:
            - '00340434161094015749'
        tracking_url:
          type:
            - string
            - 'null'
          format: uri
          description: Public tracking URL.
          examples:
            - https://track.smartsend.io/example
      required:
        - uuid
        - reference
        - identifier
        - freetext
        - gross_weight
        - length
        - width
        - height
        - total_net_amount
        - tax_amount
        - duty_amount
        - items
        - tracking_number
        - tracking_url
      description: >-
        Parcel input and booking result. Parcel order remains the accepted input
        order. Documents and drop-off/QR code arrays are on Shipment. Tracking
        numbers and URLs are booking results; tracking state, estimated delivery
        and events are retrieved through the separate tracking endpoints and
        require tracking access.
    MoneyAmount:
      type: object
      description: >-
        A monetary amount with its explicit ISO 4217 currency. Within one
        shipment, all non-null amounts must use the same currency.
      required:
        - value
        - currency
      properties:
        value:
          type: integer
          description: >-
            Amount in the currency's minor unit. For example, 3920 means DKK
            39.20.
          examples:
            - 3920
        currency:
          $ref: '#/components/schemas/CurrencyCode'
      additionalProperties: false
      examples:
        - value: 3920
          currency: DKK
    ShipmentContentType:
      type: string
      description: Type of contents in the shipment
      enum:
        - commercial_goods
        - returned_goods
        - gift
        - commercial_sample
        - documents
        - other
    ShipmentDocument:
      type: object
      properties:
        uuid: 4a1224ee-9c57-4372-bd5c-293e6b8bc1f4
        print_status: 07964c6f-3e0c-490a-bf68-5c428b86871a
        name: e0004003-6241-4e70-a178-8ae2b9bcef45
        filename: 5e72734e-0719-4405-8964-fdde40bf280a
        types: 51f0d3c4-576a-4228-a951-69247bcbc8c0
        format: 355c6402-c7fc-47b9-94d4-77a3d40ce80d
        mime_type: 19954ca1-7f51-41f1-af5f-9b3982d7fd76
        size_bytes: 506715e7-49b3-4b0a-ab96-4ae378717764
        width: eb9f29c8-eddc-4f4f-893d-a827690df086
        height: 56c7e7e3-379f-489c-9a0e-a643970ada3a
        page_count: 7b91528e-dfca-4061-b7cb-bc9fa2919fa5
        url: ef703d37-5769-4f39-ab7e-c4600394d0fe
        url_expires_at: 448f51d4-6eaf-4b93-b6a1-47bc5b383772
        description: c3ca4045-c53c-4df3-8552-de39dddb50da
        created_at: 8a78531f-8fa6-487c-a27b-54f5927eaf13
        updated_at: b956f6f3-5de1-4374-a911-30afaf4fa3d4
      required:
        - uuid
        - print_status
        - name
        - filename
        - types
        - format
        - mime_type
        - size_bytes
        - width
        - height
        - page_count
        - url
        - url_expires_at
        - description
        - created_at
        - updated_at
      description: >-
        Document metadata embedded in its shipment. The source is identified by
        the enclosing shipment and is omitted here. Other fields have the same
        meaning as on the document endpoints.
    QrCode:
      type: object
      properties:
        url:
          type: string
          description: Signed URL to the ready-to-display QR image.
          format: uri
          examples:
            - https://downloads.example.com/codes/ORDER-1042.png
        url_expires_at:
          type: string
          format: date-time
          description: >-
            Expiry of this image URL, not the validity period of the carrier
            code. Retrieve Shipment again to refresh.
          examples:
            - '2026-09-16T10:15:02Z'
      required:
        - url
        - url_expires_at
      description: >-
        A QR image used when handing in the shipment. This is not a Document or
        a parcel relation.
    CarrierSummary:
      type: object
      properties:
        code:
          type: string
          description: Carrier code.
          examples:
            - postnord
        name:
          type: string
          description: Carrier display name.
          examples:
            - PostNord
        logo_url:
          type:
            - string
            - 'null'
          format: uri
          examples:
            - https://assets.example.com/carriers/postnord/logo.svg
        icon_url:
          type:
            - string
            - 'null'
          format: uri
          examples:
            - https://assets.example.com/carriers/postnord/icon.svg
      required:
        - code
        - name
        - logo_url
        - icon_url
      description: >-
        Display-ready carrier identity, without embedding its full service
        catalogue.
    Addon:
      type: object
      required:
        - code
        - name
      properties:
        code:
          type: string
          description: Addon code (SCREAMING_SNAKE_CASE)
          examples:
            - SIGNATURE
        name:
          type: string
          description: Localized human-readable addon name
          readOnly: true
          examples:
            - Signature
    PickupPoint:
      type: object
      properties:
        uuid:
          type: string
          description: Resource UUID.
          format: uuid
          examples:
            - 99999999-9999-4999-8999-999999999999
        code:
          type: string
          description: Carrier service-point code.
          examples:
            - '12345'
        name:
          type: string
          description: Display name.
          examples:
            - Example Parcel Shop
        address:
          $ref: '#/components/schemas/Address'
      required:
        - uuid
        - code
        - name
        - address
      description: Compact pickup-point snapshot for the carrier in delivery.carrier.code.
    DateTimeWindow:
      type: object
      required:
        - earliest
        - latest
      properties:
        earliest:
          type: string
          format: date-time
          description: Inclusive beginning of the window (RFC 3339).
          examples:
            - '2025-01-02T00:00:00Z'
        latest:
          type: string
          format: date-time
          description: Inclusive end of the window (RFC 3339).
          examples:
            - '2025-01-04T23:59:59Z'
      description: >-
        A bounded time window with earliest <= latest. Its owning field
        identifies whether it is an estimate or a requested delivery choice.
    Incoterm:
      type: string
      description: International Commercial Terms for trade
      enum:
        - EXW
        - FCA
        - CPT
        - CIP
        - DAP
        - DPU
        - DDP
    MerchantParty:
      type: object
      required:
        - reference
        - identifier
        - uri
        - address
        - contact
        - identifiers
      description: >-
        Merchant (webshop) party details. Direction-stable: the merchant is
        always the merchant, also on return shipments where they receive the
        parcel. Optional in requests — when omitted it is resolved from team
        settings: the default sender address for outbound shipments, or the
        team's return address for return shipments (falling back to the default
        sender address when not configured).
      properties:
        reference:
          type:
            - 'null'
            - string
          description: Human-readable reference visible externally
          examples:
            - SHOP-DK
        identifier:
          type:
            - 'null'
            - string
          description: System identifier for internal integrations
          examples:
            - shop-1
        uri:
          type:
            - 'null'
            - string
          format: uri
          description: URI linking to this party (URL, deep link, or any URI scheme)
          examples:
            - https://shop.example.com
        address:
          $ref: '#/components/schemas/Address'
        contact:
          $ref: '#/components/schemas/Contact'
        identifiers:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/PartyIdentifiers'
    CustomerParty:
      type: object
      required:
        - reference
        - identifier
        - uri
        - address
        - contact
        - identifiers
      description: >-
        Customer (consumer) party details. Direction-stable: the customer is
        always the customer, also on return shipments where they dispatch the
        parcel.
      properties:
        reference:
          type:
            - 'null'
            - string
          description: Human-readable reference visible to the customer
          examples:
            - CUSTOMER-2048
        identifier:
          type:
            - 'null'
            - string
          description: System identifier for internal integrations
          examples:
            - customer-2048
        uri:
          type:
            - 'null'
            - string
          format: uri
          description: URI linking to this party (URL, deep link, or any URI scheme)
          examples:
            - https://shop.example.com/admin/customers/2048
        address:
          $ref: '#/components/schemas/Address'
        contact:
          $ref: '#/components/schemas/Contact'
        identifiers:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/PartyIdentifiers'
    Weight:
      type: object
      description: >-
        A non-negative weight with an explicit unit. Within one shipment,
        parcel, item and dangerous-goods weights must use the same unit.
      required:
        - value
        - unit
      properties:
        value:
          type: number
          minimum: 0
          description: Weight in the specified unit.
          examples:
            - 1500
        unit:
          $ref: '#/components/schemas/WeightUnit'
      additionalProperties: false
      examples:
        - value: 1500
          unit: g
    Distance:
      type: object
      description: >-
        A non-negative physical length or distance with an explicit unit. Within
        one shipment, all parcel dimensions must use the same unit.
      required:
        - value
        - unit
      properties:
        value:
          type: number
          minimum: 0
          description: Length or distance in the specified unit.
          examples:
            - 123.4
        unit:
          $ref: '#/components/schemas/DimensionUnit'
          description: >-
            Unit of the value. Service-point distances use metres; document
            dimensions and printer paper sizes use millimetres, independently of
            parcel dimensions.
      examples:
        - value: 123.4
          unit: m
    ShipmentParcelItem:
      type: object
      description: Individual item within a parcel
      properties:
        reference:
          type:
            - 'null'
            - string
          description: >-
            Public reference, e.g. order number or SKU, which may be forwarded
            to the carrier or printed. Not necessarily unique.
          examples:
            - TSHIRT-BLUE-M
        identifier:
          type:
            - 'null'
            - string
          description: >-
            Private integration reference, e.g. a database ID. Not used for
            deduplication and not forwarded to carrier labels. Not necessarily
            unique.
          examples:
            - order-line-9001
        uri:
          type:
            - 'null'
            - string
          format: uri
          description: >-
            URI linking to this item (product page URL, deep link, or any URI
            scheme)
          examples:
            - https://shop.example.com/products/blue-t-shirt
        image_url:
          type:
            - 'null'
            - string
          format: url
          description: URL for an product thumbnail image
          examples:
            - https://www.example.com/products/1234-image1.jpeg
        sku:
          type:
            - 'null'
            - string
          description: Stock keeping unit identifier
          examples:
            - PROD-001
        location:
          type:
            - 'null'
            - string
          description: Warehouse location
          examples:
            - AA-01-B45-C
        name:
          type:
            - 'null'
            - string
          description: Product name
          examples:
            - Widget
        description:
          type:
            - 'null'
            - string
          description: Product description for customs
          examples:
            - Two blue cotton T-shirts
        tariff_code:
          type:
            - 'null'
            - string
          description: HS/customs tariff code
          examples:
            - '8471300000'
        country_of_origin:
          type:
            - 'null'
            - string
          minLength: 2
          maxLength: 2
          description: ISO 3166-1 alpha-2 country code of origin
          examples:
            - CN
        quantity:
          type: number
          exclusiveMinimum: 0
          description: Quantity represented by this item line.
          examples:
            - 2
        total_net_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Total value for all quantities excluding tax.
          examples:
            - value: 15920
              currency: DKK
        tax_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Total tax for all quantities.
          examples:
            - value: 3980
              currency: DKK
        duty_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Total duty for all quantities.
          examples:
            - value: 5572
              currency: DKK
        net_weight:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/Weight'
          description: Weight of all items on this line excluding packaging.
          examples:
            - value: 550
              unit: g
        cost_amount:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/MoneyAmount'
          description: Cost of all items excluding tax and duty.
          examples:
            - value: 5300
              currency: DKK
        dangerous_goods:
          type:
            - 'null'
            - array
          items:
            $ref: '#/components/schemas/DangerousGood'
          description: Dangerous goods contained in this item
      required:
        - reference
        - identifier
        - uri
        - image_url
        - sku
        - location
        - name
        - description
        - tariff_code
        - country_of_origin
        - quantity
        - total_net_amount
        - tax_amount
        - duty_amount
        - net_weight
        - cost_amount
        - dangerous_goods
    CurrencyCode:
      type: string
      description: ISO 4217 currency code.
      pattern: ^[A-Z]{3}$
      examples:
        - DKK
    Address:
      type: object
      required:
        - address_lines
        - postal_code
        - city
        - country
        - administrative_area
      properties:
        address_lines:
          type:
            - 'null'
            - array
          items:
            type: string
          maxItems: 3
          description: Street address lines (e.g., street name, building, floor)
          examples:
            - - 3200 Whitehaven St. NW
              - Building A, Floor 2
        postal_code:
          type:
            - 'null'
            - string
          description: >-
            Postal/ZIP code. Always a string, even when the value is purely
            numeric.
          examples:
            - 20008-4351
        city:
          type: string
          description: City
          examples:
            - Washington
        country:
          type: string
          minLength: 2
          maxLength: 2
          description: ISO 3166-1 alpha-2 country code
          examples:
            - US
        administrative_area:
          type:
            - 'null'
            - string
          minLength: 2
          maxLength: 3
          description: >-
            The sub-national subdivision code (e.g., state, province, or
            department) representing the suffix part of the ISO 3166-2 standard.
            This field should contain only the characters following the hyphen.
            For example, for 'US-NY', provide 'NY'; for 'JP-13', provide '13'
          examples:
            - DC
    Contact:
      type: object
      required:
        - name_lines
        - company
        - email
        - phone
      description: Contact information for a party
      properties:
        name_lines:
          type: array
          items:
            type: string
          minItems: 1
          maxItems: 2
          description: Name lines (e.g., person name, company name, department)
          examples:
            - - John Doe
              - Att. Finance department
        company:
          type:
            - 'null'
            - string
          description: Company or organization name
          examples:
            - Acme Corp
        email:
          type:
            - 'null'
            - string
          format: email
          description: Email address
          examples:
            - john@example.com
        phone:
          type:
            - 'null'
            - string
          description: Phone number with country code
          examples:
            - '+4512345678'
    PartyIdentifiers:
      type: object
      description: Tax and trade identifiers for customs clearance
      properties:
        vat:
          type:
            - 'null'
            - string
          description: VAT identification number
          examples:
            - DK12345678
        eori:
          type:
            - 'null'
            - string
          description: Economic Operators Registration and Identification number (EU)
          examples:
            - DK1234567890123
        gb_eori:
          type:
            - 'null'
            - string
          description: GB EORI number for UK customs
          examples:
            - GB123456789000
        tax_id:
          type:
            - 'null'
            - string
          description: Tax identification number
          examples:
            - DK1234567890
        voec:
          type:
            - 'null'
            - string
          description: VOEC (VAT on E-Commerce) number for Norway
          examples:
            - '2000123'
      required:
        - vat
        - eori
        - gb_eori
        - tax_id
        - voec
    WeightUnit:
      type: string
      description: Unit of measurement for weight
      enum:
        - g
        - kg
        - lb
        - oz
      examples:
        - g
    DimensionUnit:
      type: string
      description: Unit of measurement for dimensions
      enum:
        - mm
        - cm
        - m
        - in
      examples:
        - cm
    DangerousGood:
      type: object
      required:
        - un_number
        - class
        - un_packing_group
        - tunnel_restriction_code
        - net_weight
        - quantity
        - environmentally_hazardous
      properties:
        un_number:
          type: string
          description: UN number (e.g., '1202', '1950')
        class:
          type: string
          description: Dangerous goods class (e.g., '1', '2.1', '3', '8')
        un_packing_group:
          type:
            - 'null'
            - string
          description: UN packing group (e.g., 'I', 'II', 'III')
        tunnel_restriction_code:
          type:
            - 'null'
            - string
          enum:
            - A
            - B
            - C
            - D
            - E
            - null
          description: ADR tunnel restriction code. A=no restrictions, E=most restrictive
        net_weight:
          anyOf:
            - type: 'null'
            - $ref: '#/components/schemas/Weight'
          description: Net weight of this dangerous good.
          examples:
            - value: 100
              unit: g
        quantity:
          type:
            - 'null'
            - number
          minimum: 0
          description: Quantity of this dangerous good
        environmentally_hazardous:
          type:
            - 'null'
            - boolean
          description: Whether this is environmentally hazardous
  examples:
    BookedShipment:
      summary: Full booked shipment
      value:
        data:
          uuid: 22222222-2222-4222-8222-222222222222
          state: booked
          invoice_number: INV-1042
          reference: ORDER-1042
          identifier: shop-order-1042
          uri: https://shop.example.com/admin/orders/1042
          delivery:
            carrier:
              code: postnord
              name: PostNord
              logo_url: https://assets.example.com/carriers/postnord/logo.svg
              icon_url: https://assets.example.com/carriers/postnord/icon.svg
            last_mile_carrier:
              code: postnord
              name: PostNord
              logo_url: https://assets.example.com/carriers/postnord/logo.svg
              icon_url: https://assets.example.com/carriers/postnord/icon.svg
            service_code: postnord_agent
            service_name: Service point
            is_pickup: true
            is_return: false
            addons:
              - code: SIGNATURE
                name: Signature
            pickup_point:
              uuid: 99999999-9999-4999-8999-999999999999
              code: '12345'
              name: Example Parcel Shop
              address:
                address_lines:
                  - Eksempelvej 20
                postal_code: '8000'
                city: Aarhus C
                country: DK
                administrative_area: '82'
            delivery_window:
              earliest: '2026-09-17T08:00:00Z'
              latest: '2026-09-17T16:00:00Z'
            incoterm: DAP
          parties:
            merchant:
              reference: SHOP-DK
              identifier: shop-1
              uri: https://shop.example.com
              address:
                address_lines:
                  - Eksempelgade 1
                postal_code: '2100'
                city: Copenhagen
                country: DK
                administrative_area: '84'
              contact:
                name_lines:
                  - Example Shop
                company: Example Shop ApS
                email: shop@example.com
                phone: '+4587654321'
              identifiers:
                vat: DK12345678
                eori: DK12345678
                gb_eori: GB123456789000
                tax_id: '12345678'
                voec: '2000123'
            customer:
              reference: CUSTOMER-2048
              identifier: customer-2048
              uri: https://shop.example.com/admin/customers/2048
              address:
                address_lines:
                  - Eksempelvej 10
                postal_code: '8000'
                city: Aarhus C
                country: DK
                administrative_area: '82'
              contact:
                name_lines:
                  - Example Customer
                company: Example Design ApS
                email: customer@example.com
                phone: '+4512345678'
              identifiers:
                vat: DK87654321
                eori: DK87654321
                gb_eori: GB987654321000
                tax_id: '87654321'
                voec: '2000456'
          parcels:
            - uuid: 33333333-3333-4333-8333-333333333333
              reference: ORDER-1042-1
              identifier: shop-parcel-1
              freetext: Gift wrapped; keep dry.
              gross_weight:
                value: 1500
                unit: g
              length:
                value: 30
                unit: cm
              width:
                value: 20
                unit: cm
              height:
                value: 15
                unit: cm
              total_net_amount:
                value: 20000
                currency: DKK
              tax_amount:
                value: 5000
                currency: DKK
              duty_amount:
                value: 0
                currency: DKK
              items:
                - reference: TSHIRT-BLUE-M
                  identifier: order-line-9001
                  uri: https://shop.example.com/products/blue-t-shirt
                  image_url: https://shop.example.com/images/blue-t-shirt.jpg
                  sku: TSHIRT-BLUE-M
                  location: A1-04
                  name: Blue cotton T-shirt, size M
                  description: Two blue cotton T-shirts
                  tariff_code: '610910'
                  country_of_origin: DK
                  quantity: 2
                  total_net_amount:
                    value: 20000
                    currency: DKK
                  tax_amount:
                    value: 5000
                    currency: DKK
                  duty_amount:
                    value: 0
                    currency: DKK
                  net_weight:
                    value: 1000
                    unit: g
                  cost_amount:
                    value: 10000
                    currency: DKK
                  dangerous_goods: null
              tracking_number: '00340434161094015749'
              tracking_url: https://track.smartsend.io/example
          total_net_amount:
            value: 20000
            currency: DKK
          tax_amount:
            value: 5000
            currency: DKK
          duty_amount:
            value: 0
            currency: DKK
          shipping_net_amount:
            value: 3920
            currency: DKK
          shipping_tax_amount:
            value: 980
            currency: DKK
          content_type: commercial_goods
          documents:
            - uuid: 44444444-4444-4444-8444-444444444444
              print_status: queued
              name: Shipping label
              filename: ORDER-1042-label.pdf
              types:
                - label
              format: pdf
              mime_type: application/pdf
              size_bytes: 18342
              width:
                value: 210
                unit: mm
              height:
                value: 297
                unit: mm
              page_count: 1
              url: https://downloads.example.com/documents/label.pdf
              url_expires_at: '2026-09-16T10:15:02Z'
              description: Print and attach the label.
              created_at: '2026-09-16T10:00:02Z'
              updated_at: '2026-09-16T10:00:02Z'
          qr_codes:
            - url: https://downloads.example.com/codes/ORDER-1042.png
              url_expires_at: '2026-09-16T10:15:02Z'
          drop_off_codes:
            - PB-12345678
          created_at: '2026-09-16T10:00:00Z'
          updated_at: '2026-09-16T10:00:02Z'
          booked_at: '2026-09-16T10:00:02Z'
          cancelled_at: null
          voided_at: null
      description: >-
        Illustrative input and booking results, including items, amounts,
        documents and drop-off codes. The available services, addons, documents
        and codes depend on the selected route. Cancellation timestamps remain
        null because this shipment is booked; the cotton items contain no
        dangerous goods.
    Unauthenticated:
      summary: 401 — Missing or invalid credentials
      value:
        message: Unauthenticated.
      description: >-
        Supply a valid API token. Repeating the same credentials does not
        resolve this response.
    PermissionDenied:
      summary: 403 — Insufficient team permission
      value:
        message: This action is unauthorized.
      description: Use credentials with the required team permission or scope.
    ResourceNotFound:
      summary: 404 — Resource unavailable to this team
      value:
        message: The requested resource was not found.
      description: >-
        Check the resource UUID and team. A missing, deleted or other-team
        resource uses the same response.
    ValidationFailed:
      summary: 422 — Validation response shape
      value:
        message: The given data was invalid.
        errors:
          field_name:
            - This field is required.
      description: >-
        Illustrative field name; actual errors name the invalid request fields.
        See shipment and batch operations for concrete examples.
    TooManyRequests:
      summary: 429 — Rate limit reached
      value:
        message: Too Many Attempts.
      description: >-
        Wait for the number of seconds in Retry-After before sending another
        request.
    ServerError:
      summary: 500 — Unexpected server failure
      value:
        message: Server Error
      description: >-
        An action may already have been accepted. Recover through its known
        resource URL or retry with the original Idempotency-Key. Include
        Request-ID when contacting support.
    ServiceUnavailable:
      summary: 503 — Temporary unavailability
      value:
        message: Service Unavailable
      description: >-
        Wait for Retry-After before retrying. Preserve the original
        Idempotency-Key for an action that may already have been accepted.
  responses:
    ApiUnauthorized:
      description: Authentication is missing or invalid.
      headers:
        Request-ID:
          $ref: '#/components/headers/Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            Unauthenticated:
              $ref: '#/components/examples/Unauthenticated'
    ApiForbidden:
      description: The authenticated principal lacks the required team permission or scope.
      headers:
        Request-ID:
          $ref: '#/components/headers/Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            PermissionDenied:
              $ref: '#/components/examples/PermissionDenied'
    ApiNotFound:
      description: The resource is absent, belongs to another team, or has been deleted.
      headers:
        Request-ID:
          $ref: '#/components/headers/Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            ResourceNotFound:
              $ref: '#/components/examples/ResourceNotFound'
    ApiValidationError:
      description: >-
        Invalid request input or reuse of an Idempotency-Key with different
        input. Upfront shipment validation creates no shipment; a failing
        batch-add request adds none of its members. Correct the fields listed in
        errors before retrying.
      headers:
        Request-ID:
          $ref: '#/components/headers/Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiValidationErrorResponse'
          examples:
            ValidationFailed:
              $ref: '#/components/examples/ValidationFailed'
    ApiTooManyRequests:
      description: Rate limit exceeded. Wait for Retry-After before retrying.
      headers:
        Request-ID:
          $ref: '#/components/headers/Request-ID'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            TooManyRequests:
              $ref: '#/components/examples/TooManyRequests'
    ApiInternalServerError:
      description: >-
        Unexpected server failure. An accepted action may already exist; recover
        using the same idempotency key or known resource URL.
      headers:
        Request-ID:
          $ref: '#/components/headers/Request-ID'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            ServerError:
              $ref: '#/components/examples/ServerError'
    ApiServiceUnavailable:
      description: The service is temporarily unavailable.
      headers:
        Request-ID:
          $ref: '#/components/headers/Request-ID'
        Retry-After:
          $ref: '#/components/headers/Retry-After'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiErrorResponse'
          examples:
            ServiceUnavailable:
              $ref: '#/components/examples/ServiceUnavailable'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
    oauth2:
      type: oauth2
      description: OAuth 2.0 Authorization Code flow for API access
      flows:
        authorizationCode:
          authorizationUrl: https://app.smartsend.io/oauth/authorize
          tokenUrl: https://app.smartsend.io/oauth/token
          scopes:
            members:write: Manage team members
            service-point:read: Access service points and pickup locations
            routing: Access team-specific routing (pre-shipment discovery)
            delivery-options:read: Get shipping rates and pricing
            tracking:read: Access shipment tracking information
            shipment:read: Read shipment information
            shipment:write: Create and manage shipments
            inventory:read: Read team WMS inventory levels and items
            inventory:write: Mutate team WMS inventory (move stock, update counts)
            fulfillment:read: Read team WMS fulfillment requests
            fulfillment:write: Mutate team WMS fulfillment requests (pack)
            documents:read: Read team business documents, including reports and manifests
            printing:read: Read printers and document print jobs
            printing:write: Create document print and reprint jobs

````