Skip to main content
Early preview. The ReconLayer API is under active development. Endpoints, request/response shapes, and defaults may change. Breaking changes will be announced in advance β€” pin to a known-good integration and watch the changelog before upgrading.
Every request to a /v1/* route must carry a Bearer credential. ReconLayer accepts two kinds of credential on the same Authorization header, and resolves your organization from whichever one you present.
Authorization: Bearer <credential>
/health, /openapi.json, /openapi.yaml, the /docs API explorer, and everything under /webhooks/* are public and do not require a credential. Every other route β€” including all /v1/* routes β€” runs through the authentication hook below before it is handled.

Two credential types

ReconLayer inspects the bearer token and routes it to one of two verification paths:
Use an API key for servers, scripts, and backend integrations. API keys are created via POST /v1/api-keys and are the recommended credential for any code that calls ReconLayer outside the dashboard.
curl https://api.reconlayer.com/v1/payment-intents \
  --header "Authorization: Bearer rl_live_AbCdEfGhIjKlMnOpQrStUvWxYz0123456789..."
The organization, scopes, and key status are all resolved server-side from the key itself β€” you do not need to send x-organization-id alongside a valid API key.

How ReconLayer tells the two apart

The API key check is a cheap prefix match before any database lookup: any bearer token that starts with rl_live_ is treated as an API key and verified against the hashed key store. Anything else is treated as a Clerk session token and verified with Clerk.
rl_live_<43 url-safe base64 characters>   β†’  ~32 bytes of entropy
Only the SHA-256 hash of the full key is stored. The plaintext key is returned exactly once, in the response body of POST /v1/api-keys β€” copy it immediately, because it cannot be retrieved again. The response also includes a non-secret prefix (the key’s first 16 characters, e.g. rl_live_AbCd1234) that is safe to display in the dashboard for identification.

API keys: scopes, status, and expiry

Each API key carries:
FieldDescription
prefixNon-secret display prefix (e.g. rl_live_AbCd1234), safe to show in UI.
scopesAn array of free-form scope strings assigned at creation, used by your own authorization logic.
statusOne of active, expired, or revoked, derived from revokedAt / expiresAt.
expiresAtOptional ISO 8601 expiry. After this time the key is rejected.
revokedAtSet when a key is revoked; revoked keys are rejected immediately.
lastUsedAtUpdated on every successful verification.
A request authenticated with an API key whose status is not active (revoked, or past expiresAt) is rejected with:
401 Invalid, revoked, or expired API key
{
  "error": "unauthorized",
  "message": "Invalid, revoked, or expired API key."
}
Manage keys via POST /v1/api-keys, GET /v1/api-keys, PATCH /v1/api-keys/{keyId}, and DELETE (revoke) /v1/api-keys/{keyId}.
API key management routes require a signed-in dashboard session (a Clerk session token), not another API key. Calling them with an API key returns 403 forbidden.

Organization resolution

ReconLayer is multi-tenant: every record belongs to an organization, and every authenticated request resolves to exactly one organizationId.
  • API key requests β€” the organization is whatever the key was issued for. You do not need to send x-organization-id.
  • Clerk session requests β€” the organization comes from the active organization on the Clerk session. If the session does not carry one, send x-organization-id and ReconLayer will use it as a fallback.
Authorization: Bearer <clerk-session-token>
x-organization-id: org_acme
If neither the credential nor the header resolves to an organization, the request fails before it reaches any handler.

Missing or invalid credentials

SituationStatusBody
No Authorization header, or it doesn’t start with Bearer 401{ "error": "unauthorized", "message": "Missing bearer credential. Provide an API key or session token." }
Token looks like an API key (rl_live_...) but is unknown, revoked, or expired401{ "error": "unauthorized", "message": "Invalid, revoked, or expired API key." }
Token is not a valid Clerk session, or resolves to no organization401{ "error": "unauthorized", "message": "Invalid session token or no active organization." }

Signed-in-user-only routes

A small set of routes require a real dashboard user β€” for example, creating, updating, or revoking API keys, and other account-administration actions. If you call one of these with an API key, ReconLayer responds:
403 Signed-in session required
{
  "error": "forbidden",
  "message": "This action requires a signed-in dashboard session."
}
The same shape (error: "forbidden") is also returned when a signed-in user lacks the workspace permission required for an action β€” for example, a user without the cases_action permission calling a write endpoint.

Local development bypass

When running the API locally with AUTH_DEV_BYPASS=1 (and NODE_ENV is not production), requests may omit the Authorization header entirely and instead identify their organization with x-organization-id alone:
curl http://localhost:3001/v1/payment-intents \
  --header "x-organization-id: org_dev"
This bypass is intended for local development and the test suite only. It refuses to activate when NODE_ENV=production, so it cannot accidentally ship enabled. In any real deployment, always present a Bearer credential as described above.

Next steps

  • API design principles β€” idempotency, business-level uniqueness, and how writes are deduplicated.
  • Idempotency β€” the Idempotency-Key header in depth.
  • Errors β€” the error envelope and status codes you’ll see across the API.
  • Quickstart β€” get an API key and make your first authenticated call.