Four steps to your first verified result.
Chirograph Verify is a server-to-server API plus an optional hosted widget. This guide reflects the real endpoints and payloads the service exposes.
Four steps to a verified result.
-
Get a tenant and an API key
Tenants are provisioned by an operator. Your secret
X-API-Keyauthenticates server-to-server calls and is only ever stored server-side as a hash. -
Request a verification challenge
Each challenge is single-use and scoped to a user reference.
Create a challengePOST /v1/challenge (X-API-Key: your server secret) { "tenant_id": "UUID_OF_YOUR_TENANT", "user_reference": "user@example.com", "redirect_url": "https://app.example.com/auth/callback", "purpose": "authenticate" } → WebAuthn PublicKeyCredentialRequestOptions (the challenge) -
The user approves on their device
Start a hosted flow with the widget, or drive the ceremony yourself with the returned options. The hosted page is served from the Chirograph origin so origin and relying-party checks always match.
-
Submit the assertion and get a verified result
Submit the assertionPOST /v1/verify (X-API-Key: your server secret) { "challenge_id": "CHALLENGE_UUID", "response": { "id": "...", "rawId": "...", "type": "public-key", "response": { "clientDataJSON": "...", "authenticatorData": "...", "signature": "..." } } } → { "verified": true, "device_trust_score": 87 }
Start a WebAuthn flow from your site.
The widget SDK (public/widget.js) starts an origin-bound, single-use hosted flow with a publishable widget key. The ceremony happens on the Chirograph origin — never in an iframe, never via your JavaScript.
In the browser
On your server
Your backend redeems the opaque result server-to-server so a redirected user is never treated as verified by itself:
Redemption is single-use and tenant-scoped. Origin and redirect allowlists are configured per widget client.
Learn about verifications asynchronously.
A successful verification can enqueue a verification.completed event delivered to your HTTPS endpoint. Each delivery carries an HMAC-SHA256 signature over the exact body bytes and a stable delivery_id, so you can verify authenticity and deduplicate.
Set your webhook URL and signing secret in the tenant dashboard. Delivery is asynchronous with a bounded retry schedule; failures never change a verification result.
Public surface at a glance.
| Route | Auth | Purpose |
|---|---|---|
POST /v1/challenge | X-API-Key | Create a single-use WebAuthn verification challenge. |
POST /v1/verify | X-API-Key | Verify an assertion and return a boolean result + trust score. |
POST /v1/widget/flows | X-Widget-Key + Origin | Start a hosted WebAuthn flow. |
POST /v1/widget/redeem | X-API-Key | Redeem an opaque flow result server-to-server. |
GET/POST /dashboard/* | dashboard session | Tenant usage, settings, API-key rotation, webhooks. |
POST /v1/billing/flutterwave/webhook | provider signature | Inbound Flutterwave billing webhook (idempotent). |
Example values are illustrative, not valid credentials. Integration guidance lives in the repository docs.