Skip to main content
rial has two kinds of API key, and where each one is allowed to live is the whole point — the same split Stripe uses between a secret key and a publishable key.
Secret keys (rk_secret_…) must be kept confidential and used exclusively within server-side environments. Never expose these tokens in client-side applications, mobile codebases, or browsers.
A rial operator mints your keys today — pk_ keys are minted per tenant, plaintext returned once at mint time; only a hash is stored afterwards. If you’re integrating and don’t have one yet, ask your rial contact.

Making a request

Server-to-server calls (POST /v1/verifications, GET /v1/verifications/:id, …) send the key as a bearer token:
A key that fails to match is rejected with 401 — there’s no separate “invalid format” response to distinguish a typo from a revoked key.

The Kotlin SDK’s publishableKey

The same pk_live_… / pk_test_… key is what you pass into the Kotlin SDK client-side, embedded in the app:
It authenticates the SDK’s own capture endpoints (upload URL, capture submit, answers) the same way — Authorization: Bearer pk_test_… against Staging, pk_live_… against Production. It’s the same tenant-scoped key type your backend can use to call the Verifications API directly; the difference is where it’s allowed to live. Treat pk_live_… as safe to embed in a shipped app the way you’d treat any publishable key — it identifies your tenant, it isn’t a secret that grants account-management access.

Environments

The capture link you hand your end-user needs no key at all: possession of the verification id in the URL is the credential for the capture flow (same trust model as a Stripe payment-intent client_secret) — see the API reference for the full set of auth modes, including the dashboard session cookie and the signed-request mode used by rial’s own integrations.

Next: how a verdict is built

What status and verdict mean, and what each fraud signal checks.