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

# Get tracking

> Either code returns the whole shipment: every event from the OpenBorder label and every carrier label linked to it. `results` holds one entry and `not_found` is empty, the same envelope as the batch lookup.



## OpenAPI

````yaml /api-reference/tracking.json get /api/v1/tracking/{tracking_code}
openapi: 3.0.0
info:
  title: OpenBorder Tracking API
  description: >-
    Tracking events for shipments whose label OpenBorder generated.


    ## Authentication


    Send your API key in the `X-OpenBorder-Api-Key` header on every request. A
    key covers one or more brands, and the

    tracking endpoints need the `tracking:read` scope. `GET /api/v1/me` works
    with any valid key and tells you

    which brands and scopes it has.


    ## Brands


    You only ever see shipments of the brands on your key. A code that belongs
    to another brand gets the same 404 as a code

    that doesn't exist.


    ## Rate limits


    Each key gets 120 requests per minute in a fixed window. A batch lookup

    counts once, however many codes it holds. Every response past authentication
    carries `RateLimit-Limit`,

    `RateLimit-Remaining` and `RateLimit-Reset` (plus the `X-RateLimit-*`
    equivalents), and going over returns 429.

    Requests rejected with 401 or 403 don't count.


    ## Reading events


    Order events by `sequence`, not `timestamp`. Carriers send events late and
    out of order, and some send only a date.

    `status` is one of a fixed set of milestones. Anything we can't map to one
    is `Unknown`, and `message`

    keeps the carrier's own wording.
  version: v1
  contact: {}
servers:
  - url: https://api.openborder.com
    description: Production
security: []
tags: []
paths:
  /api/v1/tracking/{tracking_code}:
    get:
      tags:
        - Tracking
      summary: >-
        Get the tracking events of one shipment, by OpenBorder label or carrier
        tracking code
      description: >-
        Either code returns the whole shipment: every event from the OpenBorder
        label and every carrier label linked to it. `results` holds one entry
        and `not_found` is empty, the same envelope as the batch lookup.
      operationId: TrackingController_getTracking
      parameters:
        - name: tracking_code
          required: true
          in: path
          description: An OpenBorder label (`OB_LABEL_...`) or a carrier tracking code
          example: OB_LABEL_MNM631582
          schema:
            type: string
        - name: If-None-Match
          in: header
          description: >-
            The ETag of a previous response. Returns 304 with no body when it
            still matches.
          required: false
          schema:
            type: string
      responses:
        '200':
          description: The shipment and its events
          headers:
            RateLimit-Limit:
              description: Requests this key may make per minute
              schema:
                type: integer
                example: 120
            RateLimit-Remaining:
              description: Requests left in the current window
              schema:
                type: integer
                example: 117
            RateLimit-Reset:
              description: Seconds until the window resets
              schema:
                type: integer
                example: 42
            X-RateLimit-Limit:
              description: Same as RateLimit-Limit
              schema:
                type: integer
                example: 120
            X-RateLimit-Remaining:
              description: Same as RateLimit-Remaining
              schema:
                type: integer
                example: 117
            X-RateLimit-Reset:
              description: When the window resets, in Unix epoch seconds
              schema:
                type: integer
                example: 1790000000
            ETag:
              description: Send it back in If-None-Match to get a 304 when nothing changed
              schema:
                type: string
                example: W/"4ea-sahiy1qZzzkKtIO6eqvnKV3TDgQ"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrackingResponse'
        '304':
          description: >-
            Nothing changed since that ETag. No body. Counts against the rate
            limit.
          headers:
            RateLimit-Limit:
              description: Requests this key may make per minute
              schema:
                type: integer
                example: 120
            RateLimit-Remaining:
              description: Requests left in the current window
              schema:
                type: integer
                example: 117
            RateLimit-Reset:
              description: Seconds until the window resets
              schema:
                type: integer
                example: 42
            X-RateLimit-Limit:
              description: Same as RateLimit-Limit
              schema:
                type: integer
                example: 120
            X-RateLimit-Remaining:
              description: Same as RateLimit-Remaining
              schema:
                type: integer
                example: 117
            X-RateLimit-Reset:
              description: When the window resets, in Unix epoch seconds
              schema:
                type: integer
                example: 1790000000
        '401':
          description: >-
            The API key is missing ("API key required in header:
            X-OpenBorder-Api-Key") or unknown, expired or revoked ("Invalid or
            expired API key")
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiError'
                example:
                  statusCode: 401
                  message: Invalid or expired API key
                  error: Unauthorized
        '403':
          description: >-
            The key lacks the tracking:read scope ("Insufficient scopes"),
            covers no active brand ("API key covers no active brand"), or was
            refused ("API key was refused")
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiError'
                example:
                  statusCode: 403
                  message: Insufficient scopes
                  error: Forbidden
        '404':
          description: >-
            The code doesn't resolve to a shipment this key can read. A code
            that belongs to another brand gets this exact response too, so a 404
            says nothing about whether the code exists.
          headers:
            RateLimit-Limit:
              description: Requests this key may make per minute
              schema:
                type: integer
                example: 120
            RateLimit-Remaining:
              description: Requests left in the current window
              schema:
                type: integer
                example: 117
            RateLimit-Reset:
              description: Seconds until the window resets
              schema:
                type: integer
                example: 42
            X-RateLimit-Limit:
              description: Same as RateLimit-Limit
              schema:
                type: integer
                example: 120
            X-RateLimit-Remaining:
              description: Same as RateLimit-Remaining
              schema:
                type: integer
                example: 117
            X-RateLimit-Reset:
              description: When the window resets, in Unix epoch seconds
              schema:
                type: integer
                example: 1790000000
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiError'
                example:
                  statusCode: 404
                  message: Tracking code not found
                  error: Not Found
        '429':
          description: Over the per key rate limit. Wait RateLimit-Reset seconds.
          headers:
            RateLimit-Limit:
              description: Requests this key may make per minute
              schema:
                type: integer
                example: 120
            RateLimit-Remaining:
              description: Requests left in the current window
              schema:
                type: integer
                example: 117
            RateLimit-Reset:
              description: Seconds until the window resets
              schema:
                type: integer
                example: 42
            X-RateLimit-Limit:
              description: Same as RateLimit-Limit
              schema:
                type: integer
                example: 120
            X-RateLimit-Remaining:
              description: Same as RateLimit-Remaining
              schema:
                type: integer
                example: 117
            X-RateLimit-Reset:
              description: When the window resets, in Unix epoch seconds
              schema:
                type: integer
                example: 1790000000
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiError'
                example:
                  statusCode: 429
                  message: Rate limit exceeded
        '503':
          description: >-
            We couldn't validate a key we haven't seen recently. Keys validated
            in the last few minutes keep working. Retry with backoff.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/ApiError'
                example:
                  statusCode: 503
                  message: Unable to validate API key
                  error: Service Unavailable
      security:
        - api_key: []
components:
  schemas:
    TrackingResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/TrackingResult'
        not_found:
          description: >-
            Codes that returned nothing. Always present, empty when every code
            resolved.
          example: []
          type: array
          items:
            type: string
      required:
        - results
        - not_found
    ApiError:
      type: object
      properties:
        statusCode:
          type: number
          description: The HTTP status code, repeated
          example: 404
        message:
          type: string
          description: What went wrong. Safe to log, not meant for end customers.
          example: Tracking code not found
        error:
          type: string
          description: The HTTP reason phrase. Absent on 429.
          example: Not Found
      required:
        - statusCode
        - message
    TrackingResult:
      type: object
      properties:
        tracking_code:
          type: string
          description: The code as sent in the request
          example: OB_LABEL_MNM631582
        brand_code:
          type: string
          description: >-
            The brand the shipment belongs to, always one of the brands on the
            calling key
          example: acme
        order_reference:
          type: string
          nullable: true
          description: The merchant's order reference as it reached us
          example: '#L1234'
        latest_tracking_status:
          $ref: '#/components/schemas/TrackingStatus'
          description: Status of the highest sequence event
          example: Delivered
        tracking_updates:
          description: Every event we hold for the shipment, highest sequence first
          type: array
          items:
            $ref: '#/components/schemas/TrackingUpdate'
      required:
        - tracking_code
        - brand_code
        - order_reference
        - latest_tracking_status
        - tracking_updates
    TrackingStatus:
      type: string
      enum:
        - InfoReceived
        - InTransit
        - OutForDelivery
        - AttemptFail
        - AvailableForPickup
        - Delivered
        - Exception
        - Undeliverable
        - Unknown
    TrackingUpdate:
      type: object
      properties:
        sequence:
          type: number
          description: >-
            Order events by this. Allocated when we ingest the event and
            strictly increasing within a shipment. Opaque and gapped: a jump
            between values does not mean events are missing.
          example: 918342207
        status:
          $ref: '#/components/schemas/TrackingStatus'
          example: Delivered
        message:
          type: string
          description: The carrier's own description, unmodified
          example: Delivered to recipient
        timestamp:
          type: string
          nullable: true
          description: >-
            When the carrier says the event happened, ISO-8601 in UTC. Display
            this, do not sort on it.
          example: '2026-09-21T17:22:00.000Z'
        timestamp_precision:
          $ref: '#/components/schemas/TimestampPrecision'
          description: >-
            day means the carrier sent only a date and the time component is
            ours
          example: second
        location:
          $ref: '#/components/schemas/TrackingLocation'
      required:
        - sequence
        - status
        - message
        - timestamp
        - timestamp_precision
        - location
    TimestampPrecision:
      type: string
      enum:
        - second
        - day
        - unknown
    TrackingLocation:
      type: object
      properties:
        city:
          type: string
          nullable: true
          example: Toronto
        province:
          type: string
          nullable: true
          example: Ontario
        country:
          type: string
          nullable: true
          description: ISO-3166 alpha-2
          example: CA
        raw:
          type: string
          nullable: true
          description: The carrier's location string, verbatim
          example: TORONTO, ON M5V
      required:
        - city
        - province
        - country
        - raw
  securitySchemes:
    api_key:
      type: apiKey
      in: header
      name: X-OpenBorder-Api-Key

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.