KYC SaaS API

Multi-tenant REST API to verify your users’ identity: document, CPF, facial biometrics, liveness, screening and automated decision. Heavy processing runs asynchronously — you create the verification, collect the selfie via link/QR and track the result by polling or webhook.

Base URL (production) https://api.pureface.io
Authentication OAuth2 client_credentials → JWT
Format JSON · multipart · RFC 3339 (UTC)
Rate limit 120 req/min per tenant

Authentication

The recommended flow is OAuth2 client_credentials: exchange client_id + client_secret for a short-lived JWT (1h) and send it as Bearer on every /v1/* call. There is no refresh token — on expiry (401), simply re-authenticate.

1. Get a token

# Exchange the credential for a JWT
curl -X POST https://api.pureface.io/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"client_credentials","client_id":"kyc_live_...","client_secret":"..."}'
# 200 OK
{ "access_token": "eyJhbGciOiJIUzI1NiI...", "token_type": "Bearer", "expires_in": 3600 }

2. Call the API with the JWT

# Use the token on all /v1/* routes
curl https://api.pureface.io/v1/verifications/<id> \
  -H "Authorization: Bearer <access_token>"

Verification lifecycle

PENDING PROCESSING AWAITING_FACE PENDING_DECISION APPROVED REJECTED MANUAL_REVIEW

Endpoints

Verifications

POST /v1/auth/token Public

Exchanges client_id + client_secret for an access_token (JWT).

POST /v1/verifications Bearer

Creates a verification with holder data + document image. Returns id and status PENDING.

GET /v1/verifications/{id} Bearer

Returns the current state and result. Poll until a terminal status.

POST /v1/verifications/{id}/face-check Bearer

Generates the facial capture session: capture_url + QR code as base64 PNG.

POST /v1/verifications/{id}/erase Bearer

Right to erasure (LGPD): anonymizes PII and removes binaries. Idempotent.

Facial revalidation

POST /v1/verifications/{id}/revalidate Bearer

Re-checks only the face (liveness + match) of an already-approved customer, without resubmitting a document.

GET /v1/revalidations/{id} Bearer

Retrieves the revalidation result (poll until terminal status).

Usage & invoices

GET /v1/usage Bearer

Aggregated usage for the period, by billable event type.

GET /v1/invoices Bearer

Lists your closed invoices. Use /v1/invoices/{id} for the detail.

Capture & health

GET /s/{token} Session

Validates the capture session before requesting the camera.

POST /s/{token}/capture Session

Receives the selfie + liveness frames and queues the facial analysis.

GET /healthz Public

Health of dependencies (PostgreSQL, Redis, MinIO).

Webhooks

Instead of polling, receive a signed POST when the verification is decided (verification.decided event). Each delivery is signed with your hmac_key in the X-KYC-Signature header (HMAC-SHA256 of the raw body) — always validate before trusting the payload.

# POST verification.decided · signed with X-KYC-Signature
{
  "verification_id": "b3f1c2d4-...",
  "outcome": "APPROVED",
  "score": 0.94,
  "risk_score": 0.05,
  "maker_checker_required": false
}

Need credentials?

Talk to our team to provision your tenant and issue client_id, client_secret and hmac_key.

Talk to our team