Troubleshooting
This page is organized by what you are seeing, not by error code. Find your symptom, read the cause, run the check. For the exhaustive code-by-code reference, see Errors.
Every check runs against the live sandbox at
https://phosra-api-sandbox-production.up.railway.app — no key required for the
reads below. Set it once:
export BASE=https://phosra-api-sandbox-production.up.railway.appFirst: decode any error in five seconds
Every error carries the same three fields. Read them in this order:
code— the HTTP status.4xxis your request;5xxis ours.class— (OCSS routes only) the machine failure class. Branch on this.failed_step— (403 standing failures only) the exact check that rejected you.
# Pretty-print any error and its class
curl -s "$BASE/api/v1/providers/did:ocss:nope/connect" | python3 -m json.tool
# {
# "error": "Not Found",
# "message": "provider not found",
# "code": 404,
# "class": "not_found"
# }Grab the X-Railway-Request-Id response header before you contact support —
it lets us find your exact request in the logs.
curl -s -D - -o /dev/null "$BASE/health" | grep -i x-railway-request-id401 vs 404: which one should I be getting?
The two most-confused failures. They mean opposite things, and the API keeps them strictly separate so you always know which side the problem is on.
401 signature_invalid | 404 not_found | |
|---|---|---|
| The route | exists, and requires you to prove who you are | may or may not exist — the resource behind it doesn't |
| What's wrong | your request signature (missing, malformed, wrong key_id) | the id in the path (a DID / rule / endpoint that isn't there) |
| Re-signing helps? | Yes — fix the signature and retry | No — the thing isn't there; a retry returns 404 forever |
| Leaks existence? | No — you get 401 before any lookup | Yes, deliberately: 404 means "genuinely absent," never a silent redirect to a nearby live resource |
The trap: a signed route you call without a signature returns 401, not 404 —
even if the path is nonsense. Authentication is checked before resource lookup, so
a missing signature masks whether the resource exists at all.
# No signature on a signed route -> 401 (the id is never even looked up)
curl -s -o /dev/null -w "%{http_code}\n" -X POST "$BASE/api/v1/enforcement-confirmations" \
-H "Content-Type: application/json" -d '{}'
# 401
# An UNSIGNED read route with a bogus id -> 404 (resource lookup runs)
curl -s -o /dev/null -w "%{http_code}\n" "$BASE/api/v1/providers/did:ocss:nope/connect"
# 404Decide in one question: does this route require a request signature? If yes and you're getting 401 → fix the signature (see below). If no, or your signature is already valid and you still get 404 → the id in your path is wrong; verify it character-for-character. A 404 is terminal — do not poll it back to life.
Symptoms
Still stuck?
- 1Confirm the census is upbash
curl -s "$BASE/health" # {"status":"ok"} - 2Confirm your identity is on the Trust Listbash
curl -s "$BASE/.well-known/ocss/trust-list" | python3 -m json.tool | head - 3Capture the request id and reach out
Grab
X-Railway-Request-Idfrom the failing response and email [email protected] with the request id, thecode, theclass, and (if present) thefailed_step.