Skip to content

14. API Specification

14.1 Integrator API

Endpoint Method Auth Purpose
/v1/auth/token POST Various Get tokens
/v1/auth/register POST None Email signup
/v1/auth/otp/send POST None Send OTP
/v1/auth/password/reset POST None Reset password
/v1/auth/password/change POST User JWT Change password
/v1/auth/revoke POST User JWT Revoke token
/.well-known/jwks.json GET Public Public keys
/v1/users POST client_credentials Register user (generates or maps user_id)
/v1/users/{id} GET client_credentials Get user
/v1/users/{id} PATCH client_credentials Update user
/v1/users/{id} DELETE client_credentials Delete user
/v1/users/{id}/data GET client_credentials Export data
/v1/users/{id}/identities GET client_credentials List identities
/v1/users/{id}/identities POST client_credentials Link identity
/v1/users/{id}/identities/{type} DELETE client_credentials Unlink
/v1/kyc/initiate POST client_credentials Start KYC — [POST-MVP], see §7
/v1/kyc/status/{user_id} GET client_credentials Get KYC status — [POST-MVP], see §7
/v1/kyc/callback/{provider} POST Provider signature KYC provider webhook — [POST-MVP], see §7
/v1/enroll POST client_credentials Create enroll challenge (personal scanner). pos/kiosk use /v1/device/enroll instead
/v1/verify POST client_credentials Create verify challenge (1:1, includes device_id) — e-signature
/v1/challenges/{id} GET client_credentials Check challenge status
/v1/challenges/pending GET mTLS (device cert) Poll for pending challenges (personal scanner)
/v1/challenges/{id}/complete POST mTLS (device cert) Submit palm for a challenge (personal scanner)
/v1/device/transactions POST mTLS (device cert) Device-initiated palm transaction (pos/gate): scan → 1:N identify → broker authorize → in-band {decision, display_message, product_reference}. Body {scan, context, idempotency_key}. See §10
/v1/device/signup POST mTLS (device cert) POS signup mode — start: find/create Identity user by mobile, send OTP. Body {mobile}{challenge_id}
/v1/device/signup/verify POST mTLS (device cert) POS signup — verify OTP, create user if new. Body {challenge_id, code}{user_id, is_new_user, palm_enrolled}
/v1/device/consent POST mTLS (device cert) Record consent at the device for the current user (replaces vertical-backend capture). Body {user_id, consent_type, version}
/v1/device/enroll POST mTLS (device cert) Device palm enrollment: bind a captured palm to the user. Body {user_id, scan}{palm_enrolled: true}. Consent/KYC gates per §11/§13
/v1/devices GET client_credentials List devices
/v1/devices POST client_credentials Register device (tenant-scoped). Body includes device_class; for pos/gate/kiosk, bound_product + bound_action (§9.3)
/v1/devices/{id} PUT client_credentials Update device binding (bound_product, bound_action) + metadata
/v1/devices/{id} DELETE client_credentials Revoke
/v1/devices/pair POST Pairing Code Pair scanner + issue certificate. Body: {pairing_code, csr, device_info: {model, firmware, serial, hardware_id}}. Returns {device_id, certificate, ca_chain, expires_at, status}. See §9.2.1.
/v1/devices/renew POST mTLS (device cert) Renew certificate. Body: {csr} (new keypair, signed by new private key). Returns {certificate, ca_chain, expires_at}. Old cert fingerprint added to denylist on success.
/v1/clients POST Console session Create OAuth client (returns secret once)
/v1/clients GET Console session List clients for tenant
/v1/clients/{id} DELETE Console session Revoke client
/v1/clients/{id}/regenerate POST Console session Regenerate secret (returns new secret once, old one invalidated)
/v1/webhooks POST Console session Create webhook endpoint (returns signing secret once)
/v1/webhooks GET Console session List webhook endpoints for tenant
/v1/webhooks/{id} PATCH Console session Update URL or event subscriptions
/v1/webhooks/{id} DELETE Console session Delete webhook endpoint
/v1/webhooks/{id}/regenerate POST Console session Regenerate signing secret
/v1/linked-services POST Console session (Tenant Admin) Register a product backend for device-initiated routing (product_key, base_url, authorize_path, health_path, timeout_ms, fail_mode) — see §10
/v1/linked-services GET Console session List linked services for the tenant, incl. each service's health_status + last_health_check_at (§10.7)
/v1/linked-services/{id} PATCH Console session (Tenant Admin) Update a linked service (URL, health_path, timeout, fail_mode)
/v1/linked-services/{id} DELETE Console session (Tenant Admin) Remove a linked service
/v1/consent POST client_credentials Record
/v1/consent/{user_id} GET client_credentials Check
/v1/consent/withdraw POST client_credentials Withdraw
/v1/users/{user_id}/palm-restriction PUT Console session (Tenant Admin/Operator) Set per-user palm type restriction (left/right/all/disable) — see §8.11
/v1/users/{user_id}/palm-restriction GET Console session Get current restriction for user

The device-facing palm endpoints above — /v1/device/transactions, /v1/device/enroll, and the challenge-based /v1/verify / /v1/enroll / /v1/challenges/{id}/complete — carry device-reported results under the small model and scans/features under the large model; request payload and platform handling differ by the active palm model (§8.13).

14.2 Console API (MVP)

All Console API endpoints require a valid console session. The tenant_id is extracted from the session — callers cannot specify a different tenant. Platform Admin endpoints are additionally restricted by role.

Pagination: All list endpoints support ?page=1&page_size=50&sort=created_at&order=desc plus endpoint-specific filters.

Tenant Configuration

Endpoint Method Auth Purpose
/v1/tenant/config GET Console session Get current tenant configuration (all §4.5 settings)
/v1/tenant/config PATCH Console session (Tenant Admin) Partial update of tenant config — any subset of §4.5 settings (auth_methods, kyc_required, kyc_provider, palm_provider, consent_required, audit_enabled, etc.)

Platform Administration (Platform Admin only)

Endpoint Method Auth Purpose
/v1/admin/tenants GET Console session (Platform Admin) List all tenants with status and identity count
/v1/admin/tenants POST Console session (Platform Admin) Create tenant (returns tenant_id, first Tenant Admin credentials)
/v1/admin/tenants/{id} GET Console session (Platform Admin) Get tenant details + config
/v1/admin/tenants/{id} PATCH Console session (Platform Admin) Update tenant name, region
/v1/admin/tenants/{id}/suspend POST Console session (Platform Admin) Suspend tenant
/v1/admin/tenants/{id}/reactivate POST Console session (Platform Admin) Reactivate suspended tenant
/v1/admin/tenants/{id}/deactivate POST Console session (Platform Admin) Initiate deletion (30-day grace period)
/v1/admin/palm/thresholds GET Console session (Platform Admin) Get current vendor thresholds (4-element array) — see §8.12.2
/v1/admin/palm/thresholds PUT Console session (Platform Admin) Update vendor thresholds — triggers palm_thresholds_updated audit event
/v1/admin/palm/health GET Console session (Platform Admin) Last vendor health check status — see §8.12.1
/v1/admin/palm/model GET Console session (Platform Admin) Get the deployment's active palm model (small/large) + migration_status — see §8.13
/v1/admin/palm/verification-server GET/PUT Console session (Platform Admin) Get/set the deployment's verification-server connection endpoint (URL); required to run the migration script and for large-model operation — see §8.14
/v1/admin/palm/migrate POST Console session (Platform Admin) Trigger small→large migration: run the vendor script against the configured verification server, monitor, switch model. Triggers palm_model_migration_started — see §8.14

Platform SSL / Certificate Management (Platform Admin only — see §9.2.2)

Endpoint Method Auth Purpose
/v1/admin/ssl/server-cert GET Console session (Platform Admin) Get current server TLS cert metadata (issuer, subject, expiry, days remaining, fingerprint)
/v1/admin/ssl/server-cert PUT Console session (Platform Admin) Upload new server cert + key (multipart). Validates pair, hot-reloads uvicorn. Audit: server_cert_uploaded
/v1/admin/ssl/server-cert DELETE Console session (Platform Admin) Remove the server TLS cert; backend reverts to plain HTTP on next process restart (rare — only for re-running first-run setup). Audit: server_cert_deleted
/v1/admin/ssl/ca-cert GET Console session (Platform Admin) Get platform CA metadata + public cert PEM
/v1/admin/ssl/ca-cert PUT Console session (Platform Admin) Upload existing CA cert + key (for orgs migrating from a CA they already run). Audit: platform_ca_generated
/v1/admin/ssl/ca-cert/generate POST Console session (Platform Admin) Generate a new ECDSA P-256 CA keypair (self-signed, 10-year). Audit: platform_ca_generated
/v1/admin/ssl/ca-cert/regenerate POST Console session (Platform Admin) DESTRUCTIVE — same as generate, but invalidates all existing device certs. Requires explicit confirm step. Audit: platform_ca_regenerated (high-severity)
/v1/admin/ssl/device-policy GET Console session (Platform Admin) Get current device cert validity + renewal-window policy
/v1/admin/ssl/device-policy PUT Console session (Platform Admin) Update device cert policy. Audit: device_policy_changed
/v1/admin/ssl/status GET Console session (Platform Admin) Reports {server_cert_configured, platform_ca_configured, setup_complete}. Used by the SSL Settings page to decide whether to render the inline first-run setup wizard.

User Management (Console)

Endpoint Method Auth Purpose
/v1/users GET Console session List/search users. Params: ?search=&status=&kyc_status=&palm_enrolled=&page=1&page_size=50
/v1/users/{id}/suspend POST Console session (Tenant Admin) Suspend user (triggers user_suspended audit event + user.suspended webhook)
/v1/users/{id}/reactivate POST Console session (Tenant Admin) Reactivate user (triggers user_reactivated audit event + user.reactivated webhook)

Audit Logs

Endpoint Method Auth Purpose
/v1/audit-logs GET Console session Query audit logs. Params: ?event_type=&user_id=&date_from=&date_to=&page=1&page_size=50

Dashboard

Endpoint Method Auth Purpose
/v1/tenant/stats GET Console session Dashboard KPIs: total identities, active enrollments, consent opt-in rate, auth activity, KYC pipeline breakdown, user status breakdown

14.3 Console API (Post-MVP)

The following endpoints are planned but not in the initial release:

Endpoint Method Purpose
/v1/kyc/sessions GET KYC session listing with filters (status, provider, date range) — see §7
/v1/tenant/sms-config PATCH SMS provider configuration (provider, sender ID)
/v1/audit-logs/archive-search POST Long-term audit archive search (>12 months)
/v1/consent/records GET Consent record listing with filters (type, status, date range)

14.4 Response Metadata

Device Transaction Response (POST /v1/device/transactions):

The device receives only a decision and a display string — never a user_id (consistent with §9: the device is identified by its cert; the user is not exposed to it):

{
  "decision": "allow",
  "display_message": "Approved · SAR 50.00",
  "product_reference": "wal_txn_889",
  "status": "completed"
}

decisionallow / deny / not_recognized. On authorize timeout or open circuit, the platform returns the linked service's configured fail_mode (default deny) — see §10.

Verification Response (POST /v1/challenges/{id}/complete):

{
  "status": "completed",
  "challenge_id": "ch_abc",
  "user_id": "user_123",
  "confidence": 0.9997,
  "timestamp": "2026-02-25T10:00:00Z",
  "metadata": {...}
}

Integrators receive the same metadata via webhooks (verification.complete, verification.failed).

Consent in API Responses: User-related endpoints (GET /v1/users/{id}, enrollment responses) include consent_status so integrators always know the current state without a separate API call.

Errors. All error responses follow {error: {code, message, details?}}. The full error-code catalog — platform HTTP errors, palm-vendor codes, and KYC/Nafath status — is in §15 (Error Reference).