---
title: "Get Orders Page"
method: GET
path: "/orders"
tags: ["Orders"]
---

# Get Orders Page

`GET /orders`

## Request

- Base URL: `https://api.smartroutes.io/v2`
- URL: `https://api.smartroutes.io/v2/orders`
- Auth: none declared

List the orders in your depot, most recently updated first. Each order is a summary with these fields:
- `id`, `order_number`, `type` and current `status`
- `customer` (`id` and `account`)
- `created` and `updated`
- the `stops` it is planned on, with route, delivery outcome and proof of delivery
- `line_items`, as `id`s only

Fetch an order with `GET /orders/{id}` for its full details.

Filters can be combined, and each one narrows the results:
- `status`: the order's current status, case-insensitive. An unrecognised status returns `400 INVALID_INPUT`.
- `date`: orders scheduled for that day, as `YYYY-MM-DD`. Any other format returns `400 INVALID_INPUT`.
- `updated_at_min`: orders updated at or after this time. Use it to poll for changes.
- `customer_id` and `order_number`: exact match.

Results are paged. `limit` sets the page size, up to 100 (the default). The `Link` header holds the URL of the next page. Request that URL as it is, because it already carries your filters. When the `Link` header has no `rel=next` URL, you have reached the last page. See [Paging](#section/Getting-started/Paging).

## Query parameters

- `page_info` string: Information about the page for pagination. Generated by the OpenAPI
- `status` string: Status of the orders to filter.
- `customer_id` integer: SmartRoutes customer id.
- `order_number` string: Order number of the order to filter
- `updated_at_min` string, date-time: Minimum updated date and time for filtering.
- `date` string, date: Date the order is scheduled for.
- `limit` integer: Maximum number of orders to retrieve per page.

## Response `200`

Successful response

- OrdersListResponse
  - `orders` OrderListItem[], required
    - `id` integer
    - `order_number` string
    - `type` 'delivery' | 'pickup' | 'shipment': delivery, pickup or shipment. Always set — required on every create path and enforced NOT NULL at the database.
    - `status` string: Order status. SmartRoutes derives these values from line-item statuses (source: `cORDER_STATUS_TYPES` in `src/models/order-status.js`): `BOOKED`, `BOOKING_DECLINED`, `DELIVERED`, `LOADED`, `OPEN`, `PARTIALLY_BOOKED`, `PARTIALLY_BOOKING_DECLINED`, `PARTIALLY_DELIVERED`, `PARTIALLY_LOADED`, `PARTIALLY_READY_FOR_COLLECTION`, `PARTIALLY_ROUTED`, `PARTIALLY_UNDELIVERED`, `PARTIALLY_WAITING_CONFIRMATION`, `READY_FOR_COLLECTION`, `ROUTED`, `UNDELIVERED`, `WAITING_CONFIRMATION`. This is **not** a closed set. Your organisation can define its own statuses, and any of them can appear here. Call `GET /order-statuses` for the full list your organisation can use, and treat this field as a free string rather than an enum.
    - `priority` string, nullable: LOW, MEDIUM, HIGH, or null.
    - `parts` integer, nullable
    - `delivery_address` string
    - `delivery_lat` number
    - `delivery_lng` number
    - `delivery_notes` string, nullable
    - `delivery_available_days` integer[]: Days of week the delivery may be made. Empty array when the order carries no day restriction.
    - `delivery_duration` number, nullable: Service duration in minutes. Null when unset — not the same as 0.
    - `delivery_date` string, date, nullable
    - `delivery_contact_name` string, nullable
    - `delivery_contact_number` string, nullable
    - `delivery_contact_email` string, nullable
    - `pickup_address` string, nullable
    - `pickup_duration` number, nullable
    - `pickup_lat` number, nullable
    - `pickup_lng` number, nullable
    - `pickup_notes` string, nullable
    - `pickup_contact_name` string, nullable
    - `pickup_contact_number` string, nullable
    - `pickup_contact_email` string, nullable
    - `pickup_available_days` integer[]: Days of week the pickup may be made. Empty array when the order carries no day restriction.
    - `customer` Customer, nullable: Trimmed customer reference embedded in Order responses. May be `null` for orders without a customer association.
      - `id` integer, nullable
      - `account` string, nullable
    - `capacities` Capacity[]
      - `id` integer
      - `type` string
      - `capacity` number, nullable
    - `custom_fields` CustomField[]
      - `id` integer
      - `name` string
      - `value` unknown
    - `time_windows` TimeWindow[]
      - `from` string: HH:mm:ss
      - `to` string: HH:mm:ss
      - `type` string
    - `skills` string[]
    - `attachments` object[]
      - `id` integer
      - `name` string
    - `vehicle_assignment` object[], nullable
      - `vehicle_id` integer
    - `emails` object[]
      - `email` string
    - `third_party` object
      - `id` integer, nullable
    - `order_exchange` object, nullable: Present when this order is one half of an exchange (a drop + collect served together by one vehicle). The two halves share exchange_id.
      - `id` integer
      - `order_id` integer: Server-set: the id of this order. Never accepted as input.
      - `exchange_id` string: Server-minted uuid identifying the pair — identical on both halves. Never accepted as input.
      - `partner_order_id` integer: Server-set: the other half's order id. Never accepted as input.
      - `reference` string, nullable: Customer-supplied swap reference (display only). The only client-settable field — provide it on the create request (order_exchange.reference).
    - `tags` string[]
    - `stops` OrderStop[]
      - `id` integer
      - `route_id` integer
      - `address` string
      - `postcode` string
      - `phone` string, nullable
      - `lat` number
      - `lng` number
      - `planned_distance` number
      - `arrival_date` string, date
      - `departure_date` string, date
      - `estimated_arrival_time` string: HH:mm or HH:mm:ss
      - `estimated_departure_time` string: HH:mm or HH:mm:ss
      - `actual_completed_ts` string, date-time, nullable
      - `actual_completed_lat` number, nullable
      - `actual_completed_lng` number, nullable
      - `delivery_notes` string, nullable
      - `driver_notes` string, nullable
      - `actual_arrival_time` string, nullable
      - `actual_duration` number, nullable
      - `signature` string, uri, nullable
      - `signature_lat` number, nullable
      - `signature_lng` number, nullable
      - `signed_by` string, nullable
      - `photos` string[], nullable: URLs to proof-of-delivery photos for this stop. A photo appears here as soon as it is uploaded and synced, which may be before compression has finished — following the URL of a photo that is still compressing returns `202 Accepted` with a `Retry-After` header (see the photo endpoint), so be prepared to retry. `null` when there are none.
      - `tracking_link` string, uri, nullable
      - `vehicle_assignment` object, nullable
        - `vehicle_id` integer
      - `directions` object[]
        - `instruction` string
      - `driver_questionnaire_submissions` DriverQuestionnaireSubmission[]
        - `id` integer
        - `driver_questionnaire` object
          - `type` string
          - `title` string
      - `failed_reason` object, nullable
        - `reason` string
      - `tags` string[]
      - `available_days` integer[]
      - `emails` object[], nullable
        - `email` string
      - `driver_phone_calls` object[]: Calls the driver placed to this stop's contact number from the driver app, oldest first. `[]` when there are none. **These are call *attempts*, not call records.** The app hands a `tel:` URL to the device's dialler and the OS takes over, so SmartRoutes never observes the call itself. There is deliberately no status, no duration and no answered/unanswered flag — that information does not exist. Inbound calls, and calls placed outside the driver app, are not recorded at all. `initiated_at` is the driver device's own clock at the moment the call was placed; `recorded_at` is when our servers received it. Drivers work offline, so these can differ by hours, and a call can arrive with an `initiated_at` well before the `recorded_at` of calls you have already seen. Poll on `recorded_at`, not `initiated_at`, if you are looking for new activity. Absence is not proof no call was made: on iOS, a call placed with no GPS fix available is not recorded.
        - `initiated_at` string, date-time, nullable: When the driver placed the call, from the device clock. `null` if the app did not record a usable timestamp.
        - `recorded_at` string, date-time, nullable: When our servers received the record. Later than `initiated_at` — by hours if the driver was working offline.
        - `lat` number, nullable: Driver's latitude when the call was placed. `null` when no GPS fix was available.
        - `lng` number, nullable: Driver's longitude when the call was placed. `null` when no GPS fix was available.
      - `custom_fields` CustomField[]
        - `id` integer
        - `name` string
        - `value` unknown
      - `route` object
        - `id` integer
        - `date` string, date
        - `started_ts` string, date-time, nullable
    - `line_items` object[]
      - `id` integer, required: Server-set line item id.
      - `product_name` string
      - `product_code` string
      - `product_quantity` number, float
      - `quantity_outstanding` number, float, nullable: Quantity still to be fulfilled on this line item — left to deliver on a `delivery` order, left to collect on a `pickup` order. Equal to `product_quantity` before anything is fulfilled, a value in between after a partial fulfillment, `0` when exactly the ordered quantity has been fulfilled, and **negative** when more than the ordered quantity was fulfilled. Subtract it from `product_quantity` for the amount the driver has fulfilled. **Read-only:** drivers record fulfillment in the SmartRoutes mobile app; it cannot be set through this API. Notes: `null` — not `0` — when the line item is not tracked, so treat null as unknown rather than as fully fulfilled; an over-fulfillment is reported as recorded rather than clamped; stays at `product_quantity` on `shipment` orders, which are dual-leg and not yet tracked. A value still equal to `product_quantity` does not distinguish an untouched line item from one a driver attended and fulfilled nothing on — read `status` for that (`UNDELIVERED` means attended).
      - `capacities` Capacity[]
        - `id` integer
        - `type` string
        - `capacity` number, nullable
      - `status` 'BOOKED' | 'BOOKING_DECLINED' | 'CANCEL' | 'COMPLETED' | 'DECLINED' | 'DELIVERED' | 'LOADED' | 'NOT RECEIVED' | 'ON HOLD' | 'OPEN' | 'PARTIALLY_DELIVERED' | 'READY_FOR_COLLECTION' | 'RETURNED' | 'ROUTED' | 'UNDELIVERED' | 'WAITING_CONFIRMATION': Per-line-item status. `PARTIALLY_DELIVERED` appears when a line item has been partly fulfilled — partly collected on a `pickup` order or partly delivered on a `delivery` order; how much is left to fulfil is in `quantity_outstanding`. There is no separate picked-up status: completed and partial pickups both use the `DELIVERED` family. `UNDELIVERED` covers both "attended, nothing fulfilled" (in which case `quantity_outstanding` still equals `product_quantity`) and a failed visit. The other `PARTIALLY_*` values are aggregates and apply only at the order level (see `OrderStatus`). Historical rows may still carry legacy values (`CANCEL`, `COMPLETED`, `DECLINED`, `NOT RECEIVED`, `ON HOLD`, `RETURNED`); these are listed for backward compatibility but are no longer written by current SR code.
      - `date` string, date, nullable
      - `custom_fields` CustomField[]
        - `id` integer
        - `name` string
        - `value` unknown
    - `created` string, date-time
    - `updated` string, date-time

## Other responses

- `400`: Invalid input. The request body failed validation.
- `403`: Forbidden. Returned for rate-limit exhaustion (`name = FORBIDDEN`, with `details.retry_after_seconds` and `Retry-After` header) and permission gate failures (`name = PERMISSION`). Inspect `name` to disambiguate. Send `x-sr-api-features: rate-limit-429` to receive `429 RATE_LIMIT_EXCEEDED` for the rate-limit case instead, leaving `403` to mean permission failures only — see [API Features](#section/Getting-started/API-Features).
- `429`: Rate limit exceeded (`name = RATE_LIMIT_EXCEEDED`). **Only returned to callers that opt in** with the `x-sr-api-features: rate-limit-429` request header; without it the same condition returns `403` with `name = FORBIDDEN` and an otherwise identical body. See [API Features](#section/Getting-started/API-Features).
- `500`: An unexpected server error occurred. The body carries only `name` and `description`: internal details are never returned.

---

[API](https://skmtc.dev/smartroutes/apis/smartroutes-api.md) · [All operations](https://skmtc.dev/smartroutes/apis/smartroutes-api/llms.txt) · [OpenAPI document](https://skmtc.dev/smartroutes/apis/smartroutes-api/revisions/a7ea507afac7?raw)
