Articles on: Developer Documentation

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

200 OK

The request succeeded and the response body contains the data you asked for.

Read the body.

201 Created

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.

204 No Content

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.

207 Multi-Status

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

400 Bad Request

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.

401 Unauthorized

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.

403 Forbidden

The action is not permitted.

Treat this like a 401 — a permission or eligibility problem to be resolved rather than retried.

404 Not Found

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 404 on a request you expect to work is worth checking against your key.

Confirm the ID, and confirm the record has not been deleted. Do not retry unchanged.

409 Conflict

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.

422 Unprocessable Entity

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.

423 Locked

The organisation is temporarily locked because it is being migrated between regions, so writes are not accepted. This response carries the machine-readable code TENANT_MIGRATING.

Pause and retry later. Migrations are planned and time-limited. Branch on the TENANT_MIGRATING code if you want to show your users a specific message.

429

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.

498

A non-standard code meaning the authentication token has expired.

Obtain a fresh token, then retry the request once.

500 Internal Server Error

Something went wrong on our side.

Retry with backoff. If it persists, contact support with the timestamp and the request details.

502 Bad Gateway

A service SuperPath depends on failed or returned something unusable.

Retry with backoff.

503 Service Unavailable

A service is temporarily unavailable.

Retry with backoff.


Note: SuperPath returns 401 for permission denials as well as for authentication failures, so do not read a 401 as "my API key is wrong" without also checking the role of the user the key belongs to. A 403 is 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-6b7f8a0d3e55


A 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 required


Some 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 message or error, parse it defensively. A helper that tries JSON, falls back to the raw string, and then reads whichever of message or error is present will keep your error logs readable across every case.


Handling errors in your integration


  1. Branch on the status code first. It is the only part of the response with a stable, documented contract.
  2. Retry only what is worth retrying. Retry 429, 500, 502 and 503 with exponential backoff and jitter. Retry 498 once, after refreshing your token. Retry 423 later, on a longer delay, because a region migration takes longer than a normal transient blip.
  3. Never blind-retry a 400, 401, 403, 404, 409 or 422. These describe something about the request itself, so the same request will fail the same way. Log it and surface it.
  4. 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 400 or 404 in your logs tells you almost nothing.
  5. 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.
  6. Be careful about retrying writes. A 500 on 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.
  • 404 has 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 401 is 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

Was this article helpful?

Share your feedback

Cancel

Thank you!