Bob Go API
The Bob Go API lets you rate, book and track shipments across every courier Bob Go supports, using a single integration. Everything the dashboard does is available over the same HTTP API.
What you can build with it:
- Rates at checkout: show your buyers the shipping options you have configured in Bob Go, priced by your own rules, while they are still in the cart.
- Order synchronisation: push orders into Bob Go as they are placed, and keep them in step as they change.
- Shipment submission: quote couriers, book the one you want, and pull the waybill.
- Tracking: read a shipment's tracking events, or have Bob Go push them to you as they happen.
Base URLs
| Environment | Base URL |
|---|---|
| Sandbox | https://api.sandbox.bobgo.co.za/v2 |
| Production | https://api.bobgo.co.za/v2 |
Sandbox is a full copy of the platform wired to test courier accounts. Nothing you create there is collected or billed, and the account is pre-loaded with credit so you can create as many test shipments as you like. Sign up at sandbox.bobgo.co.za and create a key under Settings → API keys.
Going live is a two-line change: swap the base URL and swap the API key. The request and response shapes are identical.
In this Bruno collection the environment sets BobGoHost to the host, and each
request carries the /v2 prefix in its path.
Conventions
- All requests and responses are JSON. Send
content-type: application/jsonon any request with a body. - Paths are prefixed with
/v2, e.g.POST /v2/rates,POST /v2/shipments. - Field names are
snake_case. - Money is a number in ZAR (rands), e.g.
152.35. Amounts are VAT-inclusive unless the field name says otherwise (rate_amountvsrate_amount_excl_vat). - Dimensions are centimetres (
_cm), weights are kilograms (_kg). - Timestamps are RFC 3339, e.g.
2026-09-05T08:30:00Z. - An array in the query string is written as a JSON array with no spaces, e.g.
?status=["in-transit","delivered"]. A space after a comma is not rejected, but the value then matches nothing: a list comes back empty, and a waybill request finds no shipments to print. - Every request acts on the account your API key belongs to. Bob Go reads the
account from the key, so you do not send
account_id, and a value you do send is replaced rather than checked.
Objects that appear in more than one endpoint, addresses and parcels, always have the same shape wherever they appear. See Important concepts.
Listing and pagination
List endpoints accept limit and offset, plus order_by and order
(asc / desc). order only applies together with order_by: send both, and
the sort is ascending unless order is desc. Without order_by the
endpoint's default sort is used and order is ignored. Responses wrap
the page in an object with a count of the whole result set, not of the page.
This is GET /v2/shipments?limit=2 on an account with 348 shipments, trimmed to
two fields a shipment:
{
"shipments": [
{ "id": 4455123, "tracking_reference": "UATCG4X7Q2" },
{ "id": 4455122, "tracking_reference": "UATCG4X7PZ" }
],
"count": 348
}
Defaults and caps are per endpoint, so read the page for the one you are
calling. GET /v2/orders and GET /v2/shipments both default to 100 and cap
at 100. GET /v2/packages has no default and no cap: it returns every package
on the account unless you set limit yourself.
Errors
Failures return an HTTP status code and a single message field:
{
"message": "Collection contact name is required."
}
| Status | Meaning |
|---|---|
400 |
The request failed validation. The message says what. |
401 |
The API key was not recognised. See Authentication. |
403 |
No API key was sent, the key may not make this call, or your plan does not include API access. |
404 |
No such path, or no such record on your account. Some endpoints report a missing record as a 400 or an empty list instead. |
423 |
The account has been closed. |
429 |
Too many requests on this key. Back off and retry. |
500 |
Something failed on our side. A few validation failures also come back as 500, so read the message before retrying. |
503 |
The request ran past the gateway's limit of about 30 seconds, usually while waiting on a courier. The body is {"message": "Service Unavailable"}. Retry later. |
Treat the message as human-readable text for your logs and support team, not as a stable machine-readable code. Branch on the status code instead.