Unirail

Errors

One error envelope for every endpoint, with a stable code to branch on.

Every endpoint shares one error shape. The HTTP status says what class of problem it is; data.code is the stable value to branch on, and data.explanation is something you can show.

{
  "code": "BAD_REQUEST",
  "status": 400,
  "message": "…",
  "data": {
    "code": "invalid_request",
    "param": "amount.value",
    "requestId": "…",
    "explanation": { "key": "…", "vars": {}, "message": "…" }
  }
}

Quote requestId when you contact support.

Codes

data.codeHTTPWhat happenedWhat to do
invalid_request400The request didn't match the contract; param names the field.Fix the request.
unauthorized401No key, or the key is wrong, revoked or expired.Check Authorization.
forbidden403The key can't do this, for example a missing scope.Use a key with the right scope.
not_found404No such object in this environment.Check the id and that you're using the right environment's key.
idempotency_conflict409The idempotency key was used for a different request.Make the key more specific.
quote_expired409The quote passed its expiresAt, or was already used.Quote again and ask the user again.
quote_changed409Something the digest covers no longer holds.Quote again and ask the user again.
route_infeasible422No route can serve the request.Show the explanation; suggest another account.
connection_not_ready422The provider connection isn't ready, for example missing credentials.Fix the connection in the dashboard.
provider_unavailable503The provider is down or unreachable.Retry later with the same idempotency key.
provider_rejected502The provider refused the request.Show the explanation.
rate_limited429Too many requests.Back off and retry.

In the SDK

The SDK throws an error carrying the same status and data:

try {
  await unirail.paymentIntents.create({ quote: quote.id, digest: quote.digest, returnUri }, { context: { idempotencyKey } });
} catch (error) {
  const code = (error as { data?: { code?: string } }).data?.code;
  if (code === "quote_expired" || code === "quote_changed") {
    return requote();
  }
  throw error;
}

On this page