> ## 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.

# Tracking Integration

> Retrieve tracking information for any shipping label generated through OpenBorder. Supports tracking lookups for both individual and multiple tracking numbers in a single request.

OpenBorder supports a Tracking API, which provides real-time tracking updates for any shipping label that was generated by OpenBorder. The API supports individual tracking number lookups, as well as bulk requests, so that clients can efficiently ingest tracking information.

## Authentication

The Tracking API uses an `X-OpenBorder-Api-Key` header. A valid API key must be included in the header field of every API request. Note that a Bearer token authentication will not work for this API.

A production API key is provided by OpenBorder. To obtain a production key, please contact your OpenBorder representative.

# Individual Tracking Number Request

## Request

<table>
  <colgroup>
    <col width="100" />

    <col width="508" />
  </colgroup>

  <thead>
    <tr>
      <th>Method</th>
      <th>Endpoint</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>GET</td>
      <td>**[https://api.openborder.com/api/v1/tracking/\\\{tracking\_number\\}](https://api.openborder.com/api/v1/tracking/\\\{tracking_number\\})**</td>
    </tr>
  </tbody>
</table>

Clients can use OpenBorder's individual tracking number endpoint to query tracking events for a single tracking number.

## Response Example

Upon a successful request, the API will return a list of tracking events, with detailed event descriptions. The tracking numbers will always be in a `results` array.

```json Success Response theme={"system"}
{
    "results": [
        {
            "tracking_code": "OB1234567890",
            "brand_code": "abcmerchant",
            "order_reference": "9876543211",
            "latest_tracking_status": "InTransit",
            "tracking_updates": [
                {
                    "sequence": 85124492,
                    "status": "InTransit",
                    "message": "Carrier pick-up from the US Processing Center for Export",
                    "timestamp": "2026-11-04T00:02:36.046Z",
                    "timestamp_precision": "second",
                    "location": {
                        "city": "Chicago",
                        "province": "IL",
                        "country": "US",
                        "raw": null
                    }
                },
                {
                    "sequence": 85123799,
                    "status": "InfoReceived",
                    "message": "Label creation",
                    "timestamp": "2026-11-03T19:47:48.000Z",
                    "timestamp_precision": "second",
                    "location": {
                        "city": null,
                        "province": null,
                        "country": null,
                        "raw": "FedEx System"
                    }
                }
            ]
        }
    ],
    "not_found": []
}
```

```json Error Response theme={"system"}
{
    "statusCode": 404,
    "message": "Tracking code not found",
    "error": "Not Found"
}
```

### Response Fields

* `tracking_code`: The tracking number associated with the shipment. All tracking events in the response correspond to this tracking number.
* `brand_code`: Identifies the merchant associated with the tracking number, allowing clients to determine which merchant the shipment belongs to.
* `order_reference`: The merchant's order reference, as OpenBorder received it. This is `null` when no reference is available.
* `latest_tracking_status`: The shipment's most recent tracking status, classified and standardized by OpenBorder. It is the `status` of the first event in `tracking_updates`, or `Unknown` when there are no events yet. This field will always contain one of the following structured statuses: `InfoReceived`, `InTransit`, `OutForDelivery`, `AttemptFail`, `AvailableForPickup`, `Delivered`, `Exception`, `Undeliverable`, or `Unknown`.
* `tracking_updates`: An array containing all available tracking events for the shipment. Events are ordered newest first, so the first element is the most recent event and the last element is the oldest.
  * `sequence`: The number to order events by. It increases with every event OpenBorder receives for a shipment. The values have gaps, so a jump between two numbers does not mean any events are missing.
  * `status`: The standardized tracking status assigned by OpenBorder. This field may contain one of the structured statuses listed above.
  * `message`: The tracking event description provided directly by the carrier. This field preserves the carrier's original event description.
  * `timestamp`: The date and time when the carrier says the event occurred, expressed in UTC. Use it for display, but sort events by `sequence` instead, because carriers sometimes send events late or out of order. It may be `null`.
  * `timestamp_precision`: How exact `timestamp` is. `second` means the carrier sent a full date and time. `day` means the carrier sent only a date, so the time portion should be ignored. `unknown` means there is no timestamp.
  * `location`: An object containing the available location information associated with the tracking event, such as city, province, and country. Individual fields may be `null` if the carrier does not provide the corresponding information. The `raw` field contains the original location data received from the carrier.

# Bulk Tracking Number Request

## Request

<table>
  <colgroup>
    <col width="100" />

    <col width="508" />
  </colgroup>

  <thead>
    <tr>
      <th>Method</th>
      <th>Endpoint</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>POST</td>
      <td>[https://api.openborder.com/api/v1/tracking/lookup](https://api.openborder.com/api/v1/tracking/lookup)</td>
    </tr>
  </tbody>
</table>

Clients can also bulk track multiple tracking numbers, by sending a request to OpenBorder's bulk-track endpoint. This endpoint supports up to 50 tracking numbers per request.

## Request Example

```json Request Body theme={"system"}
{ 
    "tracking_codes": ["OB12345", "OB989898"] 
}
```

## Response Example

```json Success Response theme={"system"}
{
    "results": [
        {
            "tracking_code": "OB1234",
            "brand_code": "abcmerchant",
            "order_reference": "9876543211",
            "latest_tracking_status": "InfoReceived",
            "tracking_updates": [
                {
                    "sequence": 85124492,
                    "status": "InfoReceived",
                    "message": "Label creation",
                    "timestamp": "2026-11-03T19:47:48.000Z",
                    "timestamp_precision": "second",
                    "location": {
                        "city": null,
                        "province": null,
                        "country": null,
                        "raw": null
                    }
                }
            ]
        },
        {
            "tracking_code": "OB9898",
            "brand_code": "xyzmerchant",
            "order_reference": "9865765788",
            "latest_tracking_status": "InfoReceived",
            "tracking_updates": [
                {
                    "sequence": 85125310,
                    "status": "InfoReceived",
                    "message": "Label creation",
                    "timestamp": "2026-11-04T19:47:48.000Z",
                    "timestamp_precision": "second",
                    "location": {
                        "city": null,
                        "province": null,
                        "country": null,
                        "raw": null
                    }
                }
            ]
        }
    ],
    "not_found": []
}
```

```json No Codes Found theme={"system"}
{
    "results": [],
    "not_found": [
        "abc132",
        "ob3232"
    ]
}
```

Upon a successful request, the API will return a `results` array, where each element in the array corresponds to one tracking number. The structure of the response is identical to the individual lookup endpoint described above.

If one or more of the tracking numbers in the request body cannot be found, the request will *not* error. Instead, the tracking number(s) will be recorded in the `not_found` array. If none of the tracking numbers can be found, the request still returns `200`, with every tracking number in the `not_found` array and an empty `results` array. Duplicate tracking numbers in a request are only returned once.

# Possible Error States

The possible error states are similar between the individual tracking number endpoint and the bulk lookup endpoint.

### Invalid Request Body

**HTTP Status:** `400`

**Response:**

```json theme={"system"}
{
    "statusCode": 400,
    "message": [
        "tracking_codes must be an array"
    ],
    "error": "Bad Request"
}
```

**Cause:**\
This error occurs on the bulk lookup endpoint, when the request body is not filled out correctly. That includes a body that is not valid JSON, a missing or empty `tracking_codes` array, an array holding anything other than non-empty strings, or more than 50 tracking numbers.

**Solution:**\
Ensure that the request body only contains a `tracking_codes` array, and that the array is correctly formatted. Split larger lists into requests of 50 tracking numbers or fewer.

### Unauthorized API Key

**HTTP Status:** `401`

**Response:**

```json theme={"system"}
{
    "statusCode": 401,
    "message": "API key required in header: X-OpenBorder-Api-Key",
    "error": "Unauthorized"
}
```

**Cause:**\
This error occurs on all of the endpoints, when an OpenBorder API key is not included. If the key is included but is unknown, expired, or revoked, the message is `Invalid or expired API key` instead.

**Solution:**\
Ensure that a header is added to the API request, and it should be called, `X-OpenBorder-Api-Key` (the case does not matter). Verify that the OpenBorder API key is correctly copied. If this error persists, reach out to your OpenBorder contact for further troubleshooting.

### Forbidden API Key

**HTTP Status:** `403`

**Response:**

```json theme={"system"}
{
    "statusCode": 403,
    "message": "Insufficient scopes",
    "error": "Forbidden"
}
```

**Cause:**\
The API key is valid but cannot be used for this request. `Insufficient scopes` means the key does not have the `tracking:read` scope that the tracking endpoints require. `API key covers no active brand` means none of the merchants on the key are currently active.

**Solution:**\
Call `GET /api/v1/me` to see the scopes and merchants on your key, then reach out to your OpenBorder contact to have the key updated.

### Invalid Tracking Number

**HTTP Status:** `404`

**Response:**

```json theme={"system"}
{
    "statusCode": 404,
    "message": "Tracking code not found",
    "error": "Not Found"
}
```

**Cause:**\
This error occurs on the individual lookup endpoint, when the tracking number cannot be resolved to the client's organization.

**Solution:**\
Verify that the tracking number is correct **and** that OpenBorder generated the label. OpenBorder only provides tracking data for labels that it generated - if the label originated from a different provider, then tracking data will not be available. If the error persists, reach out to your OpenBorder contact with the tracking number for further troubleshooting.

### Too Many Requests

**HTTP Status:** `429`

**Response:**

```json theme={"system"}
{
    "statusCode": 429,
    "message": "Rate limit exceeded"
}
```

**Cause:**\
This error can occur on any endpoint when the maximum number of requests allowed per minute has been reached.

**Solution:**\
Each API key can make 120 requests per minute, shared across all endpoints. A bulk lookup counts as one request, however many tracking numbers it contains, so prefer it over many individual lookups. Requests rejected with `401` or `403` do not count toward the limit.

Every response includes `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers. If this error occurs, pause requests for the number of seconds in `RateLimit-Reset` before retrying.

To avoid repeatedly encountering this error, implement request throttling on your side to ensure that requests remain within the allowed rate limit. It is also recommended that clients implement a retry mechanism with exponential backoff, gradually increasing the delay between subsequent retry attempts.

# Organization-Level API Access

## Request

<table>
  <colgroup>
    <col width="100" />

    <col width="508" />
  </colgroup>

  <thead>
    <tr>
      <th>Method</th>
      <th>Endpoint</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>GET</td>
      <td>[https://api.openborder.com/api/v1/me](https://api.openborder.com/api/v1/me)</td>
    </tr>
  </tbody>
</table>

Some clients operate across multiple merchants and need to retrieve tracking information for shipments belonging to different merchants within their organization. This commonly applies to 3PLs, WMSs, and Label Providers.

To support this, OpenBorder API keys are provisioned at the organization level, allowing access to tracking information for shipments across all merchants associated with that organization.

If you need to add a new merchant to your organization, contact your OpenBorder representative. Tracking information for that merchant will not be accessible through your API key until the merchant has been added to your organization.

## Response Example

```json Response Body theme={"system"}
{
    "key_id": "key_1f9d164f-196b-4047-9e81-8f1473dbf5c7",
    "scopes": [
        "tracking:read"
    ],
    "brand_codes": [
        "merchantABC",
        "merchantXYZ"
    ]
}
```


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