BouncerBouncerDocs
Session

Create a session

Creates an age verification session and returns the verify_url to send the person to. Call it from your server with your API token. Send Accept: application/json and Content-Type: application/json; without the Accept header, errors come back as redirects or HTML instead of JSON.

POST
/session

Authorization

bearerAuth

AuthorizationBearer <token>

Your organization's API token, sent as Authorization: Bearer YOUR_API_TOKEN. It looks like 1|abc123...: send all of it, including the part before the |.

An Owner or Admin creates tokens in the dashboard: open the user menu, choose Organization and go to the API Tokens section. The token is shown only once. Tokens do not expire; a revoked token stops working on the next request.

Keep tokens on your server. Never put them in browser or mobile app code.

The API Secret shown in the same section is not an API token: it verifies webhook signatures and the jwt added to your redirect.

In: header

Header Parameters

Accept*string

Must be application/json. Without it, errors come back as a redirect or an HTML page instead of JSON.

Default"application/json"
Value in"application/json"

Request Body

application/json

A JSON object. Fields not listed here are ignored.

Calls are not idempotent: every successful call creates a new session, so retrying a request creates another one. There is no test mode: every session is real and counts in your organization's data.

age_target*integer

Minimum age, in years, the person must prove. The face age estimate approves the session only when it clears this age. Otherwise the person is asked for an identity document, which must show an age of at least age_target.

Value in8 | 13 | 16 | 18 | 21 | 25 | 30
redirect_url*string

Where the person is sent after a successful verification. Bouncer adds a jwt query parameter with the signed result and keeps your existing query parameters. Nobody is redirected after a failure or when the session expires. Depending on your organization's setup, the redirect happens on its own or when the person taps a button.

Required even if you only use webhooks. Use an absolute https URL. Verify the jwt before you trust it: see Redirect.

Formaturi
Lengthlength <= 2048
webhook_url?string|null

URL that receives a POST for each event of this session. Optional.

Keep it at 255 characters or fewer: validation allows up to 2048, but a longer URL currently makes the request fail with 500 and no session is created. The host must be reachable on the public internet: deliveries to a host that resolves only to private or reserved addresses are skipped.

Treat every webhook as possibly the only delivery and confirm the result with Get session status. See Webhooks.

Defaultnull
Formaturi
Lengthlength <= 255
metadata?||null

Your own data for this session, such as your order or customer reference. It comes back in the status response, in every webhook and inside the signed jwt added to your redirect.

Send a JSON object. A JSON array is accepted too, but it becomes an object once Bouncer adds its own keys. Bouncer reserves the key facetec: do not use it.

Keep it small and leave personal data out. The API does not check its size, but a very large value makes the request fail with 500, and it travels in every response, every webhook and the redirect URL.

Defaultnull
expiration_time?integer

How long the session stays open, in seconds from creation. After expires_at the verification page shows the session as expired and no new scan can start. null is rejected.

Default300
Range60 <= value <= 3600
force_kyc?boolean

When true, the face age estimate cannot approve the session: the person must scan an identity document. Even when it is false, Bouncer asks for a document if the estimate does not clear age_target.

Unless force_verification is also true, a verification remembered in the person's browser can still complete the session without a scan. Set both to true to require a document every time. null is rejected.

Defaultfalse
force_verification?boolean

When true, the person must complete a new scan in this session. When false, a successful verification remembered in the same browser, at this age_target or higher, completes the session as soon as the page opens, without a scan. null is rejected.

Defaultfalse

Response Body

application/json

application/json

application/json

application/json

curl -X POST "https://app.bouncer.digital/api/v2/session" \  -H "Authorization: Bearer YOUR_API_TOKEN" \  -H "Accept: application/json" \  -H "Content-Type: application/json" \  -d '{    "age_target": 18,    "redirect_url": "https://shop.example.com/age/return",    "webhook_url": "https://shop.example.com/webhooks/bouncer",    "metadata": { "order_id": "ORDER-123" },    "expiration_time": 600  }'
{
  "data": {
    "id": "01a181f3-c900-7a3e-9b2d-4f6c8e1a2b3c",
    "verify_url": "https://app.bouncer.digital/verify/01a181f3-c900-7a3e-9b2d-4f6c8e1a2b3c",
    "issued_at": 1793181600,
    "expires_at": 1793182200
  }
}
{
  "message": "Unauthenticated."
}
{
  "message": "The age target must be one of: 8, 13, 16, 18, 21, 25, 30 (and 1 more error)",
  "errors": {
    "age_target": [
      "The age target must be one of: 8, 13, 16, 18, 21, 25, 30"
    ],
    "redirect_url": [
      "A redirect URL is required for the verification callback."
    ]
  }
}
{
  "message": "Server Error"
}