Skip to main content

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.

VersionWhat uses it
v1Almost every endpoint.
v2Global 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 "" and null mean 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, the types parameter 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
}
FieldWhat it holds
dataThe result: an object, a list, a single value, or null. Paged lists put their items and paging details here — see Pagination and filtering.
successtrue when the request succeeded. It is false whenever messages or errors contains anything.
messagesHuman-readable descriptions of what went wrong, in English.
errorsThe same problems in machine-readable form: each item has a code and a message.
otherMessagesNotices 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​

StatusWhen you get itBody
200 OKThe request succeeded.Envelope with success: true.
400 Bad RequestThe 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 UnauthorizedThe 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 ForbiddenThe 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 FoundSome 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 RequestsYou sent too many requests to a rate-limited endpoint.Empty. See Rate limits.
500 Internal Server ErrorSomething failed on RushHour's side.Envelope with the code services.error_occurred and a message such as An error occurred (ref …).
503 Service UnavailableA 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 codeMeaning
auth.invalid_loginThe user name or password is wrong, or the account cannot sign in.
auth.invalid_login_because_inactive_companyThe user's company is inactive.
meta.missing_permissionThe user does not have a permission the action requires.
meta.service_temporarily_unavailableA temporary failure; retry later.
services.error_occurredAn 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 message and messages may 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 and success first, and use errors[].code when 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​

  • GET requests 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 429 and 503 responses, 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.