Transport-level failures
Failures that happen at the wire layer — before a request reaches the verifier. These are ordinary TLS / connectivity conditions surfaced by your HTTP or JWT library, not RootHerald error codes. Service-level errors (auth, challenge, policy, quota) have string error values on the Shield error-codes page.
Every error RootHerald returns is a JSON body of the shape { "error": "<string>" } with the HTTP status carrying the class — see the Shield error-codes page. There is no numeric 9xxx/0xxx transport-code space, no Idempotency-Key handshake, and no application/jose+json content type. The conditions below come from your own TLS/HTTP stack; RootHerald just happens to be the server on the other end.
TLS reachability
The API is served over HTTPS at api.rootherald.io (TLS 1.2+). A handshake or connection failure surfaces as an exception from your HTTP client, not as a RootHerald JSON body. If you see one:
- Confirm your TLS stack negotiates TLS 1.2 or 1.3 with a modern cipher suite.
- Make sure your CA trust store is current. Do not pin the leaf certificate — certificate rotation will break the pin. If you must pin, pin to a public CA's SubjectPublicKeyInfo, or don't pin at all.
- Allow outbound HTTPS from the host that makes the call.
JWKS reachability (token verification only)
If you opt into the token path (returnToken: true) and verify the EAT offline, your verifier fetches RootHerald's public keys from https://api.rootherald.io/.well-known/jwks.json. When that endpoint is unreachable from your runtime, JWT verification fails inside your JWT library — again, not as a RootHerald error body.
- Allow outbound HTTPS to
api.rootherald.io/.well-known/jwks.jsonfrom wherever you verify tokens. - Cache the JWKS and refresh on key rotation (the
@rootherald/nodeSDK does this for you).
Service-level errors live on the Shield page
Once the request reaches the API, any rejection is a string error value with a matching HTTP status: invalid_secret_key / invalid_api_key (401), invalid_evidence (400), challenge_expired_or_used (409), unknown_policy (422), quota_exceeded (429), and metering_unavailable (500). EK/enroll validation failures return a free-text { "error": "<reason>" } with HTTP 400. All of these are documented on the Shield error-codes page.
Retry policy
Retry transport-level failures (TLS handshake, connection reset, JWKS fetch timeout) and metering_unavailable (HTTP 500) with exponential backoff. Do not retry the definitive service errors — invalid_secret_key, invalid_evidence, unknown_policy, and free-text EK-validation 400s are your request to fix. challenge_expired_or_used needs a fresh challenge, not a blind retry, and quota_exceeded needs a plan upgrade.