Error reference
Page actions
- View as Markdown (opens in a new tab)
- Ask ChatGPT (opens in a new tab)
- Ask Claude (opens in a new tab)
ChatGPT and Claude are third-party services. The link gives them this page's public address and a short instruction. This site records nothing.
Preview: the published page may be older or missing.
Every error the API returns — status, legacy body and /api/v1 envelope — generated by calling the server, plus the requests that are clamped or empty instead.
https://docs.gurbanisoul.com/api/errors/
Every error below was produced by calling the server’s own handler, on both surfaces, when this page was
generated; CI regenerates it and fails if a status, a message or an envelope has changed. A client should
branch on the status (and, on /api/v1, the code), never on the message text.
The two shapes
/api/… (legacy) | /api/v1/… | |
|---|---|---|
| Bad parameter | 400, {"error": "invalid request: <message>"} | 400, {"error": {"code": "invalid_request", "message", "request_id"}} |
| Not found (a gap, an unknown bani) | 404, {"error": "<message>"} | 404, code not_found |
| Unknown endpoint | 400, {"error": "invalid request: unknown endpoint"} | 404, code not_found |
| Unexpected failure | 500, {"error": "internal server error"} | 500, code internal, message internal server error |
The legacy shape is frozen: the golden contract and the app depend on it byte for byte. New clients should
use /api/v1, whose request_id is the same id as the X-Request-Id header and the access log
(versioning and caching). A 500 never carries the exception; the detail is
only in the server log, under that request id.
Every error, as the server answers it
| Request | When | Status | Legacy body | /api/v1 code · message |
|---|---|---|---|---|
/api/nope | a path that is not a route | 400 · v1 404 | {"error": "invalid request: unknown endpoint"} | not_found · no such endpoint: /api/v1/nope |
/api/ang | a route that needs an id, without one | 400 | {"error": "invalid request: /api/ang requires an id"} | invalid_request · /api/ang requires an id |
/api/ang/abc | an id that is not an integer | 400 | {"error": "invalid request: integer parameter expected"} | invalid_request · integer parameter expected |
/api/ang/1234567890123 | an integer longer than 12 characters | 400 | {"error": "invalid request: integer parameter too long"} | invalid_request · integer parameter too long |
/api/search?q=naam&limit=abc | an integer parameter that is not an integer | 400 | {"error": "invalid request: integer parameter expected"} | invalid_request · integer parameter expected |
/api/shabad/1 | a comp_id that is a permanent gap | 404 | {"error": "no composition with comp_id 1"} | not_found · no composition with comp_id 1 |
/api/shabad/99999999 | a comp_id beyond the last composition | 404 | {"error": "no composition with comp_id 99999999"} | not_found · no composition with comp_id 99999999 |
/api/search?q=‹301 characters› | a search query over 300 characters | 400 | {"error": "invalid request: query too long (max 300 chars)"} | invalid_request · query too long (max 300 chars) |
/api/verify?q= | an empty claim | 400 | {"error": "invalid request: empty claim"} | invalid_request · empty claim |
/api/verify?q=‹601 characters› | a claim over 600 characters | 400 | {"error": "invalid request: claim too long (max 600 chars)"} | invalid_request · claim too long (max 600 chars) |
/api/bani | a bani without its key | 400 | {"error": "invalid request: /api/bani requires a key"} | invalid_request · /api/bani requires a key |
/api/bani/NOPE! | a key with characters a key never has | 400 | {"error": "invalid request: bad bani key"} | invalid_request · bad bani key |
/api/bani/nope | a well-formed key that is not a bani | 404 | {"error": "no bani with key nope"} | not_found · no bani with key nope |
/api/bani/japji?variant=zz | a variant that is not one of the bani’s | 400 | {"error": "invalid request: bad variant"} | invalid_request · bad variant |
/api/analytics/progression | progression without raag | 400 | {"error": "invalid request: progression requires a raag"} | invalid_request · progression requires a raag |
/api/timing/raag | a raag lookup without name | 400 | {"error": "invalid request: timing/raag requires ?name="} | invalid_request · timing/raag requires ?name= |
/api/forms?comp_id=0 | forms without a usable comp_id | 400 | {"error": "invalid request: forms requires ?comp_id="} | invalid_request · forms requires ?comp_id= |
Not errors
Most parameters are clamped to their range rather than rejected, and some malformed input simply finds
nothing. These requests all return 200; check the body, not only the status:
| Request | What happens | Status | Body (lists shown as their length, Gurmukhi as ‹Gurmukhi›) |
|---|---|---|---|
/api/ang/0 | an Ang below 1 is clamped to 1 | 200 | {"ang": 1, "lines": [23 items], "continued_from": null, "raag": null, "section": ‹Gurmukhi›, "authors": [1 item]} |
/api/ang/1431 | an Ang above 1430 is clamped to 1430 | 200 | {"ang": 1430, "lines": [57 items], "continued_from": 1429, "raag": null, "section": ‹Gurmukhi›, "authors": [1 item]} |
/api/search?q=naam&limit=999 | limit above 200 is clamped to 200 | 200 | {"mode": "theme", "concept": {…}, "results": [200 items], "related_themes": [0 items]} |
/api/lines?ids=abc | ids that are not digits are ignored | 200 | {"lines": [0 items], "note": "verbatim Gurmukhi by line id, cited by Ang"} |
/api/analytics/vaar?id=x | a Vaar id that is not a number finds no Vaar | 200 | {"vaar": null, "units": [0 items]} |
/api/word | no word: nothing to count | 200 | {"word": "", "count": 0, "lines": [0 items]} |
/api/neighbors | no line_id: no neighbours | 200 | {"line_id": 0, "level": "none", "neighbors": [0 items]} |
/api/timing/raag?name=nope | an unknown raag name: no claims | 200 | {"available": true, "raag": "nope", "claims": [0 items], "note": "no such raag"} |
Beyond a single request
404from a single-context service. A service that runs one context answers a route it does not own with404and the message/api/<route> is not served by this service. Through the public origin the gateway always sends a route to its own service, so a client only sees this when calling a function directly (bounded contexts and the gateway).503from/readyz.{"ready": false, …}when a declared table is missing, or{"ready": false, "error": "database unavailable"}./healthzis liveness only.- The platform in front. Vercel may answer before the API does, for example a timeout or a challenge
page for an unusual burst of requests. Such responses are not JSON from this API and carry no
X-Serviceheader.
Sri Guru Granth Sahib Ji — Knowledge Base wiki. Generated from commit c3d9360. Updated 24 October 2026. This copy may be out of date; the page is at https://docs.gurbanisoul.com/api/errors/