Getting Started / Errors
Errors
Every error response is shaped the same way so you can write one handler in your client.
The error envelope
Failures return JSON with this shape and the matching HTTP status code:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Request failed schema validation.",
"details": { "issues": [/* zod validation issues */] }
}
}code is always present and is your stable machine-readable identifier. message is human-readable and may change. details is optional and varies by error.
Catalogue
| Status | Code | When |
|---|---|---|
| VALIDATION_ERROR | Request body, query, or path failed Zod schema validation. details.issues lists each violation. | |
| INVALID_INPUT | Input passed schema validation but failed semantic checks (e.g. text shorter than 2 chars after trim on /v1/normalize). | |
| UNSUPPORTED_TARGET | Asked /v1/translate to map to a terminology that is not configured. | |
| INVALID_API_KEY | Missing, malformed, or revoked API key on a non-public route. | |
| NOT_FOUND | No route matched the request path/method. | |
| CONCEPT_NOT_FOUND | The requested SNOMED concept is not in the database (or has no active descriptions). | |
| NO_TRANSLATION | No active mapping exists from the source code to the requested target terminology. | |
| NO_CANDIDATES | /v1/disambiguate could not derive any candidate concepts from the input text. | |
| RATE_LIMITED | Per-minute rate limit for this API key has been exceeded. See details.ttlSeconds. | |
| INTERNAL_ERROR | Unhandled server error. Always retry-safe — open an issue if you see one. |
- VALIDATION_ERROR
Request body, query, or path failed Zod schema validation.
details.issueslists each violation. - INVALID_INPUT
Input passed schema validation but failed semantic checks (e.g.
textshorter than 2 chars after trim on /v1/normalize). - UNSUPPORTED_TARGET
Asked /v1/translate to map to a terminology that is not configured.
- INVALID_API_KEY
Missing, malformed, or revoked API key on a non-public route.
- NOT_FOUND
No route matched the request path/method.
- CONCEPT_NOT_FOUND
The requested SNOMED concept is not in the database (or has no active descriptions).
- NO_TRANSLATION
No active mapping exists from the source code to the requested target terminology.
- NO_CANDIDATES
/v1/disambiguate could not derive any candidate concepts from the input text.
- RATE_LIMITED
Per-minute rate limit for this API key has been exceeded. See
details.ttlSeconds. - INTERNAL_ERROR
Unhandled server error. Always retry-safe — open an issue if you see one.
Handling errors
A robust client treats any 5xx as transient (retry with exponential backoff) and any 4xx as a contract you violated (do not retry without changing the request). The one exception is 429 RATE_LIMITED — retry after details.ttlSeconds.
async function callObscyro<T>(input: unknown): Promise<T> {
const res = await fetch(URL, { method: "POST", body: JSON.stringify(input), headers });
if (res.ok) return res.json();
const { error } = await res.json();
if (res.status === 429) {
await new Promise((r) => setTimeout(r, error.details.ttlSeconds * 1000));
return callObscyro<T>(input);
}
throw new Error(`${error.code}: ${error.message}`);
}