API-Only Integration

The API-only approach gives you complete control over the user experience. You build the capture UI, collect documents and selfies in your own application, and submit them to Verifa for processing.

When to use API-only

  • You need full control over the user experience and camera flow
  • You’re building for a non-standard platform (kiosk, desktop, embedded device)
  • You’re integrating into an existing capture pipeline
  • You want to pre-process images before submission

Flow overview

Your App Your Server Verifa
│ │ │
│ "Start verification" │ │
│───────────────────────────────▶│ │
│ │ POST /api/v1/sessions │
│ │───────────────────────────▶│
│ │ { id, token } │
│ { session_id, token } │◀───────────────────────────│
│◀───────────────────────────────│ │
│ │ │
│ [capture documents + selfie] │ │
│ │ │
│ Upload documents │ │
│───────────────────────────────▶│ │
│ │ POST /verify/{token}/... │
│ │───────────────────────────▶│
│ │ │
│ │ POST /verify/{token}/complete
│ │───────────────────────────▶│
│ │ │
│ │ webhook: session.approved │
│ │◀───────────────────────────│

Step 1: Create a session

$curl -X POST https://api.withverifa.com/api/v1/sessions \
> -H "X-API-Key: vk_live_your_key_here" \
> -H "Content-Type: application/json" \
> -d '{
> "external_ref": "user_abc123",
> "country": "US"
> }'

Save the id and extract the token from the capture_url path. The token is used for the capture endpoints.

Before uploading any biometric data, record the user’s consent:

$curl -X POST https://api.withverifa.com/verify/{token}/consent \
> -H "Content-Type: application/json" \
> -d '{
> "consent_given": true
> }'

This records the timestamp, IP address, and consent version. Consent is required before documents or selfies can be submitted.

Step 3: Select document type

$curl -X POST https://api.withverifa.com/verify/{token}/document-type \
> -H "Content-Type: application/json" \
> -d '{
> "document_type": "drivers_license"
> }'

Supported document types: passport, drivers_license, national_id, residence_permit.

Step 4: Upload documents

Upload the front side of the ID document:

$curl -X POST https://api.withverifa.com/verify/{token}/document \
> -F "file=@id_front.jpg" \
> -F "side=front"

Upload the back side (required for driver’s licenses and national IDs):

$curl -X POST https://api.withverifa.com/verify/{token}/document \
> -F "file=@id_back.jpg" \
> -F "side=back"

Document requirements

RequirementValue
Max file size10 MB
Supported formatsJPEG, PNG, WebP, HEIC
Minimum resolution480px on shortest side
Recommended resolution1920px+ for best OCR accuracy

Documents are encrypted with AES-256-GCM immediately on receipt.

Step 5: Upload selfie

$curl -X POST https://api.withverifa.com/verify/{token}/selfie \
> -F "file=@selfie.jpg"

The selfie is compared against the photo on the ID document during face matching. For best results:

  • Well-lit, front-facing photo
  • No sunglasses or face coverings
  • Neutral expression
  • Minimum 480px resolution

Step 6: Submit additional data (optional)

If your workflow requires additional information:

$curl -X POST https://api.withverifa.com/verify/{token}/user-info \
> -H "Content-Type: application/json" \
> -d '{
> "email": "jane@example.com",
> "phone": "+15551234567",
> "address_line1": "123 Main St",
> "city": "San Francisco",
> "state": "CA",
> "zip": "94102"
> }'

Upload proof of address

$curl -X POST https://api.withverifa.com/verify/{token}/additional-document \
> -F "file=@utility_bill.pdf" \
> -F "doc_type=proof_of_address"

Step 7: Complete capture

Signal that all data has been submitted and trigger workflow processing:

$curl -X POST https://api.withverifa.com/verify/{token}/complete

The session status moves to processing and the workflow engine begins executing checks.

Step 8: Get the result

Via webhook

1{
2 "event": "session.approved",
3 "data": {
4 "session_id": "session_abc123",
5 "external_ref": "user_abc123",
6 "status": "approved"
7 }
8}

Via polling

$# Check status
$curl https://api.withverifa.com/api/v1/sessions/session_abc123 \
> -H "X-API-Key: vk_live_your_key_here"
$
$# Once completed, get full result
$curl https://api.withverifa.com/api/v1/sessions/session_abc123/result \
> -H "X-API-Key: vk_live_your_key_here"

Fraud signals

When using the API-only approach, you won’t get automatic client-side fraud signal collection (behavioral, device fingerprinting, etc.) unless you submit them manually:

$curl -X POST https://api.withverifa.com/verify/{token}/signals \
> -H "Content-Type: application/json" \
> -d '{
> "completion_time_ms": 45000,
> "device_memory": 8,
> "hardware_concurrency": 4,
> "screen_width": 1920,
> "screen_height": 1080,
> "user_agent": "..."
> }'

Server-side signals (IP analysis, document forensics, duplicate detection) run automatically regardless of integration method.

Capture endpoint reference

All capture endpoints use the token path (/verify/\{token\}/...) and do not require API key authentication — the token itself serves as the credential.

MethodPathPurpose
POST/verify/\{token\}/consentRecord biometric consent
POST/verify/\{token\}/document-typeSelect document type
POST/verify/\{token\}/documentUpload ID front or back
POST/verify/\{token\}/selfieUpload selfie photo
POST/verify/\{token\}/additional-documentUpload proof of address
POST/verify/\{token\}/user-infoSubmit email, phone, address, SSN
POST/verify/\{token\}/send-otpSend OTP verification code
POST/verify/\{token\}/verify-otpValidate OTP code
GET/verify/\{token\}/liveness-challengeGet liveness challenge nonce
POST/verify/\{token\}/signalsSubmit client-side fraud signals
POST/verify/\{token\}/completeFinalize capture and trigger processing

Error handling

Capture endpoints return 400 Bad Request for:

  • Expired token (20-minute TTL)
  • Session already completed
  • Missing consent (must be recorded before document/selfie upload)
  • File too large (>10 MB)
  • Invalid file format
1{
2 "error": "bad_request",
3 "detail": "Session token has expired. Resume the session to get a new token.",
4 "status_code": 400
5}