JBI API — Order Tracking (v3)
Endpoint: POST /customer/v3/tracking/{accountId}
Base URL: https://api.jbi.bike
Version: v3
Content-Type: application/json
Overview
This endpoint returns carrier tracking information for one or more of your orders. A single order can ship from multiple warehouse locations, and each location can produce multiple packages (tracking numbers). Results are grouped by location so you can see exactly what shipped from where.
You may look an order up by your own order number (CustomerOrderNo) or by JBI's order number (OrderId, returned in the response of the v3 Order Submission endpoint).
Optionally, add ?include=items to also receive the items and quantities that shipped from each location.
Authentication
Every request must include your API token in the request header.
Token-key: your-api-token-here
Your accountId and Token-key are provided by JBI. The token is validated per account — using a token that does not match the accountId in the URL will result in a 401 response.
URL Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
accountId |
integer | Yes | Your JBI customer account number |
Example URL:
POST https://api.jbi.bike/customer/v3/tracking/10042
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
include |
string | No | Comma-separated list of optional response sections to add. Currently supports items. |
Omit include and the response is exactly as documented before this option existed — nothing changes for existing integrations.
Example URL with items:
POST https://api.jbi.bike/customer/v3/tracking/10042?include=items
Unrecognised values in include are ignored rather than rejected, so requesting a section this API version does not yet support will not fail your request.
Request Body
The body must be a JSON array of lookup objects. Each object contains exactly one lookup key identifying the order. You may mix both key types in a single request.
[
{ "CustomerOrderNo": "1777255" },
{ "OrderId": "9844" }
]
Request Fields
| Key | Type | Required | Description |
|---|---|---|---|
CustomerOrderNo |
string | one of | Your own order number (the value you submitted when ordering). |
OrderId |
string | one of | JBI's order number, as returned by the v3 Order Submission endpoint. Faster — recommended when you have it. |
Each object must contain exactly one of these keys with a non-empty string value.
Tip: Looking up by
OrderIdis the fastest path. Lookups byCustomerOrderNoare limited to orders placed within roughly the last two weeks.
Responses
Success (HTTP 200)
Returns an array with one entry per matched order. An order is returned once, with its tracking grouped by location. Orders that are not found or have not shipped yet are included with an empty locations array — they are never silently omitted.
{
"success": true,
"data": [
{
"orderId": "9844",
"customerOrderNo": "1777255",
"locations": [
{
"locID": 101,
"packages": [
{ "trackingNumber": "1Z999AA10123456784", "carrierName": "UPS Ground", "shippedDate": "2025-06-01" },
{ "trackingNumber": "770123456789", "carrierName": "FedEx Home", "shippedDate": "2025-06-02" }
]
},
{
"locID": 104,
"packages": [
{ "trackingNumber": "1Z999AA10199887766", "carrierName": "UPS Ground", "shippedDate": "2025-06-02" }
]
}
]
},
{
"orderId": null,
"customerOrderNo": "1777256",
"locations": []
}
]
}
Success with ?include=items (HTTP 200)
The same response, with an items array added to each location:
{
"success": true,
"data": [
{
"orderId": "9844",
"customerOrderNo": "1777255",
"locations": [
{
"locID": 101,
"packages": [
{ "trackingNumber": "1Z999AA10123456784", "carrierName": "UPS Ground", "shippedDate": "2025-06-01" },
{ "trackingNumber": "770123456789", "carrierName": "FedEx Home", "shippedDate": "2025-06-02" }
],
"items": [
{ "itemId": "ABC-123", "quantity": 4 },
{ "itemId": "XYZ-9", "quantity": 1 }
]
}
]
}
]
}
Response Fields
Top-level
| Field | Type | Description |
|---|---|---|
success |
boolean | true on a successful response. |
data |
array | Array of order tracking objects (see below). |
Order Tracking Object
| Field | Type | Description |
|---|---|---|
orderId |
string | null | JBI's order number. null when the order was not found (e.g. a CustomerOrderNo with no shipments yet). |
customerOrderNo |
string | null | Your own order number. null when looked up by OrderId and not found. |
locations |
array | One entry per warehouse location that shipped this order. Empty if nothing has shipped yet. |
Location Object
| Field | Type | Description |
|---|---|---|
locID |
integer | The warehouse/location ID that shipped these packages. |
packages |
array | One entry per package (tracking number) from this location. |
items |
array | Only present when ?include=items is supplied. One entry per item shipped from this location. Empty array if no item detail is available. |
Package Object
| Field | Type | Description |
|---|---|---|
trackingNumber |
string | The carrier tracking number for the package. |
carrierName |
string | The shipping carrier's name. |
shippedDate |
string | The ship date in YYYY-MM-DD format. |
Item Object
Returned only when ?include=items is supplied.
| Field | Type | Description |
|---|---|---|
itemId |
string | The JBI item number that shipped. |
quantity |
number | Total quantity of that item shipped from this location. |
Important: items are reported per location, not per package. We do not track which individual box a given item was placed in, so
itemssits alongsidepackagesrather than inside it. The quantities describe everything that left that location for this order — across all of its tracking numbers combined.
Error Responses
All errors follow the same envelope structure:
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "Human-readable description"
}
}
HTTP 400 — Bad Request
| Code | Message | Cause |
|---|---|---|
INVALID_ACCOUNT |
Account ID must be a positive integer | The {accountId} in the URL is not a valid integer. |
INVALID_BODY |
Request body must be a valid JSON array of lookup objects | Body is empty, not valid JSON, or not a JSON array. |
HTTP 401 — Unauthorized
| Code | Message | Cause |
|---|---|---|
MISSING_TOKEN |
Token-key header is required | The Token-key header was not included in the request. |
INVALID_TOKEN |
Authentication failed | The token does not match the one on file for this account. |
HTTP 405 — Method Not Allowed
| Code | Message | Cause |
|---|---|---|
METHOD_NOT_ALLOWED |
Only POST requests are accepted | A non-POST method was used. |
HTTP 422 — Unprocessable Entity
| Code | Message | Cause |
|---|---|---|
VALIDATION_FAILED |
Each item must be an object with exactly one of: CustomerOrderNo, OrderId | An array element is not an object, has more than one key, uses an unsupported key, or has an empty/non-string value. |
When validation fails the response includes a fields object identifying the offending index:
{
"success": false,
"error": {
"code": "VALIDATION_FAILED",
"message": "Each item must be an object with exactly one of: CustomerOrderNo, OrderId",
"fields": {
"[1]": "required|object|one-of:CustomerOrderNo,OrderId"
}
}
}
HTTP 500 — Server Error
| Code | Message | Cause |
|---|---|---|
SERVER_ERROR |
An unexpected error occurred | An unhandled server-side exception. Contact JBI support with the request timestamp. |
Notes
- An order that has not shipped yet (or is not found) is returned with
locations: []rather than being omitted, so you can poll uniformly. - The same physical order may be requested by both
CustomerOrderNoandOrderIdin one call; it is returned only once. - Lookups by
CustomerOrderNoare limited to orders placed within roughly the last two weeks. For older orders, look up byOrderId. - The
itemsarray is opt-in via?include=items. Without it the response is unchanged, and the extra lookup is not performed — so there is no added latency for callers that do not need item detail. - Item quantities are aggregated per location: if a location shipped an item on more than one pick ticket, you receive a single line with the combined quantity.
Quick Reference
POST /customer/v3/tracking/{accountId} HTTP/1.1
Host: api.jbi.bike
Token-key: your-api-token-here
Content-Type: application/json
[
{ "CustomerOrderNo": "1777255" },
{ "OrderId": "9844" }
]
With shipped items included:
POST /customer/v3/tracking/{accountId}?include=items HTTP/1.1
Host: api.jbi.bike
Token-key: your-api-token-here
Content-Type: application/json
[
{ "CustomerOrderNo": "1777255" },
{ "OrderId": "9844" }
]
Document version: 1.1 — 2026-09-02 (added the optional ?include=items section)
For questions or to request API access, contact JBI.