Learn how to handle and recover from errors received from the SuperPath API
Learn how to handle and recover from errors received from the SuperPath API
In this article:
- Overview
- Success status codes
- Error status codes
- What an error response body looks like
- Handling errors in your integration
- Things to keep in mind
- FAQs
Overview
Every integration has to deal with errors sooner or later — an expired token, a record that has since been deleted, a payload that fails validation, or a transient problem on our side. The SuperPath API signals all of these through the HTTP status code, so the status code is what your integration should branch on.
The response body carries the human-readable detail. It is deliberately kept simple, and its shape varies a little depending on which error you hit, so read it defensively rather than assuming a single fixed envelope. There is more on this in "What an error response body looks like" below.
Success status codes
Status | Meaning | What to do |
|---|---|---|
| The request succeeded and the response body contains the data you asked for. | Read the body. |
| The record was created. The body contains the unique ID of the new record. | Store the returned ID — you will need it for later updates. |
| The request succeeded and there is nothing to return, which is typical of updates and deletes. | Do not try to parse a body; there is not one. |
| A request that performed several actions where some succeeded and some failed. | Inspect the body to see which individual items failed, rather than treating the whole call as a success. |
Error status codes
The following HTTP status codes are returned from the SuperPath API.

Status | Meaning | What to do |
|---|---|---|
| The request could not be understood or failed validation. This is what you get when a required field is missing, a field is the wrong type, or a bearer token is supplied in the wrong format. | Fix the request. The body names the specific field or problem. Do not retry unchanged. |
| Authentication or permission failed. This covers a missing or invalid token, a disabled user, a user who has no access to the organisation being requested — and a permission denial, where the credential is valid but the user's role is not allowed to perform that action on that record. | Check the API key and the role of the user it was created against. Do not retry unchanged, since retrying will not grant the permission. |
| The action is not permitted. | Treat this like a |
| The requested record does not exist, or the ID is wrong. It is also what you get when the API key itself cannot be found, so a | Confirm the ID, and confirm the record has not been deleted. Do not retry unchanged. |
| The record already exists. This usually means a duplicate create — for example, a user with that email address is already in the organisation. | Look the existing record up and update it instead of creating it again. |
| The request was understood but cannot be processed as sent — most often a required identifier was not specified. | Correct the request. Do not retry unchanged. |
| The organisation is temporarily locked because it is being migrated between regions, so writes are not accepted. This response carries the machine-readable code | Pause and retry later. Migrations are planned and time-limited. Branch on the |
| You have exceeded a rate limit or usage allowance. | Back off and retry. See Learn about API rate limits and how to work with them. |
| A non-standard code meaning the authentication token has expired. | Obtain a fresh token, then retry the request once. |
| Something went wrong on our side. | Retry with backoff. If it persists, contact support with the timestamp and the request details. |
| A service SuperPath depends on failed or returned something unusable. | Retry with backoff. |
| A service is temporarily unavailable. | Retry with backoff. |
Note: SuperPath returns
401for permission denials as well as for authentication failures, so do not read a401as "my API key is wrong" without also checking the role of the user the key belongs to. A403is used in a smaller number of cases, so handle both.
What an error response body looks like
Most error responses have a plain-text body containing just the message. This is what the API reference declares for its 400, 401 and 404 responses, and it is what you should expect by default:
HTTP/1.1 404 Not Found
User not found: auth id 8f21c0d4-4a1e-4f2b-9c11-6b7f8a0d3e55A validation failure returns the specific problem in the same way, which makes 400 responses genuinely useful for debugging:
HTTP/1.1 400 Bad Request
"firstName" is requiredSome responses are a JSON object instead. The generic authentication failure is one of these — a message key and nothing else:
{
"message": "You are not authorised to perform this action"
}Where SuperPath has a machine-readable code for the condition, the body carries a code alongside the message, so your integration can branch on the code rather than matching on message text. TENANT_MIGRATING on a 423 response is currently the only such code:
{
"message": "...",
"code": "TENANT_MIGRATING"
}Rate limit rejections use an error key rather than message:
{
"error": "Too many requests. Please try again later."
}Tip: Because the body may be plain text or JSON, and JSON bodies may use
messageorerror, parse it defensively. A helper that tries JSON, falls back to the raw string, and then reads whichever ofmessageorerroris present will keep your error logs readable across every case.
Handling errors in your integration
- Branch on the status code first. It is the only part of the response with a stable, documented contract.
- Retry only what is worth retrying. Retry
429,500,502and503with exponential backoff and jitter. Retry498once, after refreshing your token. Retry423later, on a longer delay, because a region migration takes longer than a normal transient blip. - Never blind-retry a
400,401,403,404,409or422. These describe something about the request itself, so the same request will fail the same way. Log it and surface it. - Log the status code and the body together. The body carries the field name or record ID that explains the failure, and without it a
400or404in your logs tells you almost nothing. - Cap your retries. An uncapped retry loop turns a transient error into sustained load, and can get you rate limited on top of the original problem.
- Be careful about retrying writes. A
500on a create is ambiguous — the record may or may not have been written. Where you can, look the record up before creating it again, or send a stable identifier of your own so duplicates are easy to spot.
Things to keep in mind
- The status code is the contract; the message text is not. Many messages are translated, and any of them can be reworded, so never match on the exact string to make a decision.
- For the same reason, the wording you see in your own tests may differ from what your customer's organisation receives.
404has two quite different meanings — the record was not found, or your API key was not found. Rule the key out before assuming the record is missing.- A
401is not always about credentials. If the same key works for other calls, the likely cause is that the user the key belongs to does not have permission for that specific action or record. - Keep your API key safe. Once created it cannot be viewed again — see Learn how to authenticate with the SuperPath API.
- If you hit an error you cannot explain, contact support@superpath.io with the endpoint, the timestamp, the status code and the response body.
FAQs
Is there a machine-readable error code on every response?
No. Codes are added only where a client needs to branch on a specific condition, and TENANT_MIGRATING on a 423 is currently the only one. For everything else, branch on the HTTP status code.
Why am I getting a 401 when my API key definitely works?
Because permission denials also return 401. The key is authenticating fine, but the user it was created against does not have the role permission needed for that action or that record. API keys inherit the permissions of the user who created them.
Why am I getting a 404 for a record I know exists?
Check the ID and the organisation first, then check the key itself — an API key that cannot be found also produces a 404. It is also worth confirming the record has not been deleted or archived since you cached its ID.
Which errors are safe to retry?429, 500, 502 and 503 with backoff; 498 once you have refreshed the token; 423 after a longer wait. Everything else needs the request to change before it will succeed.
Should I parse the error body as JSON?
Try to, but do not depend on it. Most error bodies are plain text, so your parser needs to fall back to treating the body as a string.
Updated on: 25/07/2026
Thank you!
