> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.withverifa.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.withverifa.com/_mcp/server.

# Quickstart

> Create your first verification session in 5 minutes.

This guide walks you through creating a verification session, completing the
capture flow in sandbox, and retrieving the result.

## Prerequisites

* A Verifa account ([sign up](https://app.withverifa.com))
* A sandbox API key (starts with `vk_sandbox_`)

You can find your API keys in the Verifa dashboard under **Developers > API Keys**.
Signed in? The dashboard's [Quickstart page](https://app.withverifa.com/developers/quickstart)
pre-fills these snippets with your own key for the environment you're in.

## Step 1: Create a session

#### cURL

```bash
curl -X POST https://api.withverifa.com/api/v1/sessions \
  -H "X-API-Key: vk_sandbox_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"external_ref": "quickstart_user_1"}'
```

#### Python

```python
import requests

response = requests.post(
    "https://api.withverifa.com/api/v1/sessions",
    headers={"X-API-Key": "vk_sandbox_your_key_here"},
    json={"external_ref": "quickstart_user_1"}
)
session = response.json()
print(f"Capture URL: {session['capture_url']}")
```

#### JavaScript

```javascript
const response = await fetch('https://api.withverifa.com/api/v1/sessions', {
  method: 'POST',
  headers: {
    'X-API-Key': 'vk_sandbox_your_key_here',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ external_ref: 'quickstart_user_1' }),
});
const session = await response.json();
console.log(`Capture URL: ${session.capture_url}`);
```

#### Go

```go
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    body, _ := json.Marshal(map[string]string{
        "external_ref": "quickstart_user_1",
    })
    req, _ := http.NewRequest("POST", "https://api.withverifa.com/api/v1/sessions", bytes.NewBuffer(body))
    req.Header.Set("X-API-Key", "vk_sandbox_your_key_here")
    req.Header.Set("Content-Type", "application/json")

    resp, _ := http.DefaultClient.Do(req)
    defer resp.Body.Close()

    var session map[string]interface{}
    json.NewDecoder(resp.Body).Decode(&session)
    fmt.Println("Capture URL:", session["capture_url"])
}
```

#### Ruby

```ruby
require 'net/http'
require 'json'
require 'uri'

uri = URI('https://api.withverifa.com/api/v1/sessions')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true

request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'vk_sandbox_your_key_here'
request['Content-Type'] = 'application/json'
request.body = { external_ref: 'quickstart_user_1' }.to_json

response = http.request(request)
session = JSON.parse(response.body)
puts "Capture URL: #{session['capture_url']}"
```

#### PHP

```php
$ch = curl_init('https://api.withverifa.com/api/v1/sessions');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: vk_sandbox_your_key_here',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'external_ref' => 'quickstart_user_1',
    ]),
]);

$response = curl_exec($ch);
curl_close($ch);

$session = json_decode($response, true);
echo "Capture URL: " . $session['capture_url'];
```

#### Java

```java
import java.net.http.*;
import java.net.URI;

var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.withverifa.com/api/v1/sessions"))
    .header("X-API-Key", "vk_sandbox_your_key_here")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(
        "{\"external_ref\":\"quickstart_user_1\"}"))
    .build();

var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
```

#### C\#

```csharp
using var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "vk_sandbox_your_key_here");

var content = new StringContent(
    "{\"external_ref\":\"quickstart_user_1\"}",
    System.Text.Encoding.UTF8, "application/json");

var response = await client.PostAsync(
    "https://api.withverifa.com/api/v1/sessions", content);
var session = await response.Content.ReadAsStringAsync();
Console.WriteLine(session);
```

Response:

```json
{
  "id": "session_abc123",
  "status": "pending",
  "capture_url": "https://app.withverifa.com/verify/tok_...",
  "qr_code_data_url": "data:image/png;base64,...",
  "is_sandbox": true,
  "created_at": "2026-02-01T12:00:00Z",
  "expires_at": "2026-02-01T12:20:00Z"
}
```

## Step 2: Complete the capture flow

Open the `capture_url` in your browser. In sandbox mode, the capture flow lets
you:

1. Give consent
2. Select a document type
3. Upload any image as the ID document (sandbox skips real OCR)
4. Upload any image as the selfie
5. Choose a sandbox outcome (approve, reject, or needs review)

## Step 3: Receive the webhook

If you have a webhook endpoint configured, you'll receive a `session.approved`
event:

```json
{
  "event": "session.approved",
  "created_at": "2026-02-01T12:05:00Z",
  "idempotency_key": "idk_a1b2c3d4e5f6...",
  "data": {
    "session_id": "session_abc123",
    "external_ref": "quickstart_user_1",
    "status": "approved",
    "is_sandbox": true
  }
}
```

Route on `event`, then read the resource fields from `data`. No webhook
configured yet? Skip to step 4 — you can always poll.

## Step 4: Retrieve the result

#### cURL

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123 \
  -H "X-API-Key: vk_sandbox_your_key_here"
```

#### Python

```python
result = requests.get(
    "https://api.withverifa.com/api/v1/sessions/session_abc123",
    headers={"X-API-Key": "vk_sandbox_your_key_here"}
).json()
print(f"Status: {result['status']}")
```

#### JavaScript

```javascript
const result = await fetch(
  'https://api.withverifa.com/api/v1/sessions/session_abc123',
  { headers: { 'X-API-Key': 'vk_sandbox_your_key_here' } }
).then(r => r.json());
console.log('Status:', result.status);
```

Check the `status` field. Once it's `completed`, fetch the full result:

#### cURL

```bash
curl https://api.withverifa.com/api/v1/sessions/session_abc123/result \
  -H "X-API-Key: vk_sandbox_your_key_here"
```

#### Python

```python
result = requests.get(
    "https://api.withverifa.com/api/v1/sessions/session_abc123/result",
    headers={"X-API-Key": "vk_sandbox_your_key_here"}
).json()
print(result)
```

#### JavaScript

```javascript
const result = await fetch(
  'https://api.withverifa.com/api/v1/sessions/session_abc123/result',
  { headers: { 'X-API-Key': 'vk_sandbox_your_key_here' } }
).then(r => r.json());
console.log(result);
```

```json
{
  "session_id": "session_abc123",
  "status": "approved",
  "is_sandbox": true,
  "face_match_passed": true,
  "face_match_score": 0.95,
  "age_check_passed": true,
  "extracted_age": 28,
  "extracted_data": {
    "first_name": "Jane",
    "last_name": "Doe",
    "date_of_birth": "1997-06-15",
    "document_type": "drivers_license",
    "document_issuing_state": "CA"
  },
  "processing_mode": "automatic",
  "country_used": "US",
  "created_at": "2026-02-01T12:05:00Z"
}
```

## Step 5: Set up a webhook (recommended)

Webhooks are the best way to get notified when verifications complete. In the
dashboard, go to **Developers > Webhooks** and add your endpoint URL.

You can also create webhooks via the API:

#### cURL

```bash
curl -X POST https://api.withverifa.com/api/v1/webhooks/endpoints \
  -H "X-API-Key: vk_sandbox_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/verifa",
    "enabled_events": ["session.approved", "session.declined", "session.requires-review"]
  }'
```

#### Python

```python
response = requests.post(
    "https://api.withverifa.com/api/v1/webhooks/endpoints",
    headers={"X-API-Key": "vk_sandbox_your_key_here"},
    json={
        "url": "https://your-app.com/webhooks/verifa",
        "enabled_events": [
            "session.approved",
            "session.declined",
            "session.requires-review",
        ]
    }
)
secret = response.json()["secret"]  # store securely
```

#### JavaScript

```javascript
const webhook = await fetch(
  'https://api.withverifa.com/api/v1/webhooks/endpoints',
  {
    method: 'POST',
    headers: {
      'X-API-Key': 'vk_sandbox_your_key_here',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      url: 'https://your-app.com/webhooks/verifa',
      enabled_events: [
        'session.approved',
        'session.declined',
        'session.requires-review',
      ],
    }),
  }
).then(r => r.json());
// Store webhook.secret securely for signature verification
```

The response includes a `secret` for HMAC signature verification. Store it
securely.

## What's next

You've created a session, completed verification, and retrieved the result.
Here's where to go from here:

* [How Verifa Works](/getting-started/how-verifa-works) — Understand the full architecture
* [Webhooks](/integration-guides/webhooks-guide) — Set up real-time notifications with
  signature verification
* [Workflows](/core-concepts/workflows) — Customize your verification pipeline
* [Sessions](/core-concepts/sessions) — Explore the full session lifecycle and API
* [Testing](/best-practices/testing) — Learn how to test with sandbox

## Add a "Verify" button with verifa.js

Want a popup or modal instead of a full-page redirect? Use the verifa.js SDK.
Your backend creates the session (keeping the API key secure), and the SDK
handles the frontend capture experience.

```html
<script src="https://app.withverifa.com/static/verifa.js"></script>
<script>
  document.getElementById('verify-btn').addEventListener('click', async function() {
    // Your backend creates the session and returns the capture_url
    const res = await fetch('/api/create-verification', { method: 'POST' });
    const session = await res.json();

    Verifa.open({
      captureUrl: session.capture_url,
      sessionId: session.id,
      mode: 'popup', // or 'modal'
      onComplete: function(data) {
        console.log('Verification complete:', data.sessionId);
      }
    });
  });
</script>
```

See the full [JavaScript SDK guide](/integration-guides/java-script-sdk) for framework
examples, display modes, and error handling.