REST API Reference
All endpoints use JSON request/response bodies. Authentication is via Authorization: Bearer {jwt} where noted.
Authentication
Section titled “Authentication”Initiate Authentication
Section titled “Initiate Authentication”Start a new authentication session. Generates an OTP and sends it to the mobile app via FCM push.
Rate limit: 10 requests per minute per IP.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
tokenId | string | Yes | VDS token identifier from enrollment |
serviceId | string | No | Registered service identifier |
scopes | string[] | No | Requested identity scopes |
Example Request
Section titled “Example Request”{ "tokenId": "vds-uuid-12345", "serviceId": "my-web-app", "scopes": ["identity:name", "identity:age_over_18"]}Response (200 OK)
Section titled “Response (200 OK)”{ "sessionId": "sess_abc123def456", "autoPassword": "482917", "wsToken": "hmac-websocket-token", "random": "a1b2c3d4e5f67890", "expiresAt": "2025-01-15T10:01:00Z"}Error Responses
Section titled “Error Responses”| Status | Reason |
|---|---|
400 | Missing or invalid tokenId |
403 | Enrollment revoked |
404 | Enrollment not found |
422 | Invalid scopes for service |
429 | Rate limit exceeded |
Verify Authentication
Section titled “Verify Authentication”Verify the mobile app’s OTP confirmation and ECDSA signature. Issues a JWT on success.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
sessionId | string | Yes | Session ID from initiation |
tokenId | string | Yes | VDS token identifier |
otp | string | Yes | 6-digit OTP confirmed by user |
signatureBase64 | string | Yes | ECDSA signature of {sessionId}|{otp}|{timestamp} |
timestamp | number | Yes | Unix timestamp (must be within ±30s) |
grantedScopes | string[] | No | Scopes the user chose to grant |
Example Request
Section titled “Example Request”{ "sessionId": "sess_abc123def456", "tokenId": "vds-uuid-12345", "otp": "482917", "signatureBase64": "MEUCIQD...", "timestamp": 1705312860, "grantedScopes": ["identity:name"]}Response (200 OK)
Section titled “Response (200 OK)”{ "jwt": "eyJhbGciOiJFUzI1NiIs...", "hash": "hmac-response-verification", "random": "a1b2c3d4e5f67890", "expiresAt": "2025-01-15T11:00:00Z"}Error Responses
Section titled “Error Responses”| Status | Reason |
|---|---|
400 | Invalid request body |
401 | Invalid OTP or signature |
404 | Session not found or expired |
429 | Too many verification attempts (max 3) |
Enrollment
Section titled “Enrollment”Register a mobile device with a VDS credential. See Enrollment for full details.
Rate limit: 5 requests per hour per IP.
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
vdsData | string | Yes | Encoded VDS data (Base64/Base45/hex) |
publicKeyPem | string | Yes | ECDSA P-256 public key (PEM) |
deviceId | string | Yes | Unique device identifier |
fcmToken | string | No | FCM push notification token |
Response (200 OK)
Section titled “Response (200 OK)”{ "enrolled": true, "tokenId": "vds-uuid-from-seal", "expiresAt": "2026-01-15T00:00:00Z"}Revocation
Section titled “Revocation”Revoke an enrollment. Requires a JWT with idtoken:revoke scope.
Authentication: Required (Authorization: Bearer {jwt})
Request Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
tokenId | string | Yes | Token ID to revoke |
reason | string | Yes | One of: lost_device, compromised, expired_document, user_request |
Response (200 OK)
Section titled “Response (200 OK)”{ "revoked": true, "tokenId": "vds-uuid-12345", "revokedAt": "2025-01-15T10:30:00Z"}Health & Discovery
Section titled “Health & Discovery”Health Check
Section titled “Health Check”Returns server health status including dependency checks.
Response (200 OK)
Section titled “Response (200 OK)”{ "status": "ok", "version": "1.0.0", "checks": { "database": "ok", "redis": "ok", "vdsTrust": "ok" }}The status field is "ok" when all checks pass, or "degraded" when one or more dependencies are unhealthy.
JWKS Endpoint
Section titled “JWKS Endpoint”Returns the server’s public key in JWKS format for JWT verification by relying parties.
Response (200 OK)
Section titled “Response (200 OK)”{ "keys": [ { "kty": "EC", "crv": "P-256", "kid": "idtoken-server-key-1", "alg": "ES256", "use": "sig", "x": "base64url-x-coordinate", "y": "base64url-y-coordinate" } ]}Relying parties should fetch this endpoint to verify IDToken JWTs. The kid in the JWT header matches the kid in the JWKS response.
Error Response Format
Section titled “Error Response Format”All error responses follow a consistent format:
{ "error": "Error type", "message": "Human-readable description", "statusCode": 400}Rate Limiting
Section titled “Rate Limiting”| Endpoint | Limit |
|---|---|
POST /auth/initiate | 10 per minute |
POST /enroll | 5 per hour |
POST /auth/verify | 3 attempts per session |
| Admin endpoints | 60 per minute |
Rate limit headers are included in responses:
X-RateLimit-Limit: 10X-RateLimit-Remaining: 7X-RateLimit-Reset: 1705312860