API overview
The RushHour API is a REST API served over HTTPS. Requests and responses use JSON, and almost every endpoint wraps its result in the same response envelope, so one piece of code in your client can handle success and failure everywhere.
Base URL
https://api.rushhourapp.com/api/v1
All requests must use HTTPS. Endpoint paths in these docs are relative to that base URL — for example, GET /Customers means GET https://api.rushhourapp.com/api/v1/Customers.
Versions
The version is part of every path and is always required.
| Version | What uses it |
|---|---|
v1 | Almost every endpoint. |
v2 | Global search, at /api/v2/Search. It replaces the older v1 search — use the v2 endpoint. |
Responses include an api-supported-versions header that lists the versions available for the endpoint you called.
Path segments are not case-sensitive: /api/v1/Customers and /api/v1/customers reach the same endpoint.
Making requests
- Authentication — send
Authorization: Bearer <token>on every request except sign-in. See Authentication. - Request bodies — send JSON with
Content-Type: application/json. Property names are matched without regard to case; the API itself uses camelCase. - Empty strings — an empty text value in a request body is read as
null, so""andnullmean the same thing. - Query parameters — names are not case-sensitive. Most list filters take several values by repeating the parameter:
?customers=12&customers=15. Comma-separated values are not accepted unless an endpoint says otherwise — for example, thetypesparameter of global search (/api/v2/Search) is a comma-separated list. - Where you call from — call the API from a server you control. Browser pages on other websites should not call the API directly, and credentials must never be shipped inside a web page or app.
The response envelope
A typical response looks like this (the data object is shortened):
{
"data": { "customerId": 1042, "customerName": "Example Freight LLC" },
"messages": [],
"errors": [],
"otherMessages": [],
"success": true
}
| Field | What it holds |
|---|---|
data | The result: an object, a list, a single value, or null. Paged lists put their items and paging details here — see Pagination and filtering. |
success | true when the request succeeded. It is false whenever messages or errors contains anything. |
messages | Human-readable descriptions of what went wrong, in English. |
errors | The same problems in machine-readable form: each item has a code and a message. |
otherMessages | Notices that did not stop the request, such as warnings. Each item has a message and a type. |
A failed request uses the same shape:
{
"data": null,
"messages": ["Invalid Login"],
"errors": [{ "code": "auth.invalid_login", "message": "Invalid Login" }],
"otherMessages": [],
"success": false
}
Fields that have no value are returned as null rather than left out. Response property names are camelCase.
A few endpoints return something other than JSON instead of the envelope — for example a PDF document or an image.
HTTP status codes
| Status | When you get it | Body |
|---|---|---|
200 OK | The request succeeded. | Envelope with success: true. |
400 Bad Request | The request was understood but could not be completed — for example a validation rule or business rule failed. | Envelope with success: false and the reasons in messages and errors. |
400 Bad Request (malformed input) | The body is not valid JSON, or a required field is missing or has the wrong type. | A validation problem object with title, status and an errors object keyed by field name — not the envelope. |
401 Unauthorized | The token is not valid — typically because it has expired, or because the user's password changed or the user was disabled after it was issued. | Empty. Sign in again. |
403 Forbidden | The user is signed in but is not allowed to do what the request asks — usually because they lack a permission it needs. | Usually the envelope with the code meta.missing_permission, whose message names the missing permission when there is one. A few endpoints answer 403 with an empty body, or with messages but no code, so handle a 403 whether or not it has a body. |
404 Not Found | Some endpoints use it when a record does not exist. Others answer a missing record with a 400 error or with data: null, so check both. | Varies by endpoint. |
429 Too Many Requests | You sent too many requests to a rate-limited endpoint. | Empty. See Rate limits. |
500 Internal Server Error | Something failed on RushHour's side. | Envelope with the code services.error_occurred and a message such as An error occurred (ref …). |
503 Service Unavailable | A temporary problem prevented the request from being processed. | Envelope with the code meta.service_temporarily_unavailable. Safe to retry after a short wait. |
When you contact RushHour about a 500 error, include the reference shown in its message — it lets the team find exactly what happened.
Error codes
Error codes are short identifiers in the form domain.reason, written in lower case with underscores:
| Example code | Meaning |
|---|---|
auth.invalid_login | The user name or password is wrong, or the account cannot sign in. |
auth.invalid_login_because_inactive_company | The user's company is inactive. |
meta.missing_permission | The user does not have a permission the action requires. |
meta.service_temporarily_unavailable | A temporary failure; retry later. |
services.error_occurred | An unexpected error on RushHour's side. |
How to work with them:
- Branch on the code, not the text. Codes are meant to be stable, while the English wording in
messageandmessagesmay change. - Expect new codes. New codes are added over time. Treat an unknown code as a general failure of that request.
- Not every error has a code yet. Some older endpoints return only
messages. Always check the HTTP status andsuccessfirst, and useerrors[].codewhen it is present.
Values you will see
- Timestamps are ISO 8601 strings in UTC. See Dates and time zones.
- Enumerated values such as statuses are returned as names on some fields (for example
"Active") and as numbers on others. Check which form a field uses before your code relies on it. - Identifiers are numbers for most records, and strings for a few, such as users.
Retrying safely
GETrequests are meant for reading data and are generally safe to retry.- A request that creates or changes something can take effect even if your client timed out waiting for the answer. Before repeating it, check whether the first attempt went through — otherwise you may create a duplicate.
- For
429and503responses, wait before retrying and increase the wait each time.
API reference
The API reference covers the individual endpoints. Everything on this page applies to all of them.