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

# Fulfilment

> Report whether an accepted order's tickets can be retrieved yet

# Fulfilment

Answers one question about an accepted order: **where is the actual ticket?** Retail polls this every 10 minutes for every accepted order that has not been delivered, which is the window where a buyer has paid and holds nothing.

Each system releases tickets differently: a document, a list of barcodes per seat, a transfer into an account, a parcel. Your integration translates that into one of the states below.

<Warning>
  **References here, never the credential.** This endpoint is polled and its results are logged. Return a pointer in `barcodeRef` (an id or URL you can resolve later), never the scannable barcode itself. The barcode goes out once, through [Credentials](/vendor-api/credentials).
</Warning>

## Query Parameters

<ParamField query="vendorKey" type="string" required>
  Your supplier identifier.
</ParamField>

<ParamField query="vendorOrderId" type="string" required>
  Your order id, from [Place order](/vendor-api/place-order).
</ParamField>

Answer `404` if you do not know this order. Retail reads that as "not yet" and asks again. Any other failure is reported as a failure, never as "nothing to deliver".

## Response

<ResponseField name="vendorOrderId" type="string" required>
  The order asked about.
</ResponseField>

<ResponseField name="state" type="string" required>
  | Value | Meaning | What Retail does |
  | - | - | - |
  | `pending` | Your system has the order, nothing is retrievable yet. Normal for hours. | Asks again later. |
  | `ready` | Tickets can be retrieved now. `tickets` must not be empty. | Marks the order delivered. The barcodes are then fetched through [Credentials](/vendor-api/credentials). |
  | `not_retrievable` | This delivery method never yields a credential Retail can hold, for example a transfer completed inside the box office's own app. Not a failure. | Stops polling. |
  | `shipped` | A physical ticket is with a carrier. `shipment` must be present. | Records the tracking, keeps polling until delivery. |
  | `delivered_physically` | The carrier confirmed delivery. | Closes the order. |
  | `unknown` | You could not determine the state. | Changes nothing, asks again. |
</ResponseField>

<ResponseField name="tickets" type="array" default="[]">
  One entry per admission credential. Required and non-empty when `state` is `ready`. Retail refuses a `ready` with no tickets, because that would mark an order delivered with nothing delivered.

  <Expandable title="Ticket object">
    <ResponseField name="barcodeRef" type="string" required>
      A **pointer** to one credential: an id or URL, at most 512 characters. The limit is deliberately too short to carry a document or a raw barcode.
    </ResponseField>

    <ResponseField name="seat" type="string">
      The seat this credential admits, for matching credentials to seats.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="shipment" type="object">
  Required when `state` is `shipped`.

  <Expandable title="Shipment object">
    <ResponseField name="carrier" type="string" required>Carrier name, for example `FedEx`.</ResponseField>

    <ResponseField name="trackingRef" type="string" required>
      The tracking number. **Never an admission credential.** Do not put a tracking number in `barcodeRef`: it would be rendered as a scannable code that admits nobody.
    </ResponseField>

    <ResponseField name="shippedAt" type="string">ISO 8601 time the parcel was handed to the carrier.</ResponseField>
    <ResponseField name="eta" type="string">ISO 8601 estimated arrival, if the carrier gives one.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="method" type="string">
  The delivery format actually used, with the same values as `format` on [Listings](/vendor-api/listings). Kept for the audit trail.
</ResponseField>

<ResponseField name="raw" type="any">
  Your system's payload, as evidence. Must not contain barcodes or buyer data.
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -H "X-API-Key: $GOMRY_RETAIL_API_KEY" \
    "https://integration.example.com/api/vendor/v1/fulfilment?vendorKey=acme&vendorOrderId=ord_551204"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 (ready) theme={null}
  {
    "vendorOrderId": "ord_551204",
    "state": "ready",
    "method": "eticket",
    "tickets": [
      { "barcodeRef": "tkt_551204_1", "seat": "118-12-7" },
      { "barcodeRef": "tkt_551204_2", "seat": "118-12-8" }
    ]
  }
  ```

  ```json 200 (shipped) theme={null}
  {
    "vendorOrderId": "ord_551377",
    "state": "shipped",
    "method": "physical",
    "tickets": [],
    "shipment": {
      "carrier": "FedEx",
      "trackingRef": "771234567890",
      "shippedAt": "2026-10-02T15:10:00Z",
      "eta": "2026-10-05T20:00:00Z"
    }
  }
  ```

  ```json 200 (pending) theme={null}
  { "vendorOrderId": "ord_551204", "state": "pending", "tickets": [] }
  ```
</ResponseExample>
