Skip to content

Quickstart

This walks you from a fresh merchant account to a completed, simulated verification session using a sandbox key — no real documents, camera, or wallet required. It’s the fastest way to see the session lifecycle and a signed webhook delivery end to end before you touch production traffic.

  1. Get a sandbox key.

    In your merchant dashboard, open Account → Developers and create an API key. You’ll receive a key that begins with pb_sk_test_. It is shown exactly once — copy it into your secret store immediately, because it can’t be retrieved later. If you lose it, mint a new one.

  2. Register a webhook endpoint.

    Point PersonaBlocks at an HTTPS URL your backend controls so it can receive event deliveries:

    Terminal window
    curl https://app.personablocks.io/api/v1/webhook-endpoints \
    -H "Authorization: Bearer pb_sk_test_..." \
    -H "Content-Type: application/json" \
    -d '{ "url": "https://merchant.example.com/webhooks/personablocks", "events": ["verification_session.completed"] }'

    The response carries a signing secret (pbwh_...) exactly once — store it; you’ll use it to verify delivery signatures. Registering also fires a ping event immediately so you can confirm the endpoint is reachable before you rely on it.

  3. Mint a verification session.

    Terminal window
    curl https://app.personablocks.io/api/v1/verification-sessions \
    -H "Authorization: Bearer pb_sk_test_..." \
    -H "Content-Type: application/json" \
    -d '{ "flows": ["wallet", "phone"], "test_outcome": "approved", "return_url": "https://shop.example.com/checkout/return", "metadata": { "order_id": "10042" } }'

    You get back the created session:

    {
    "id": "vs_8kQzT2mVxWyN4rLbJfHd3aGc",
    "object": "verification_session",
    "livemode": false,
    "status": "created",
    "flows": ["wallet", "phone"],
    "url": "https://app.personablocks.io/verify/pbvs_Zk3tYw9qXvB2mN7cRfHjL5dPaG8sQe1uK4oTiW6yVxA",
    "return_url": "https://shop.example.com/checkout/return",
    "kyc_session_id": null,
    "vic_id": null,
    "method": null,
    "failure_code": null,
    "created": "2026-07-11T14:30:00.000Z",
    "expires_at": "2026-07-12T14:30:00.000Z",
    "completed_at": null,
    "metadata": { "order_id": "10042" },
    "client_token": "pbvs_Zk3tYw9qXvB2mN7cRfHjL5dPaG8sQe1uK4oTiW6yVxA"
    }

    Keep two things from this response: client_token (pbvs_...), which your frontend passes to the SDK — it’s returned only on this create call — and id (vs_...), which your backend uses to correlate the session with your own records and with the webhooks it will emit.

  4. Open the session in the browser.

    Hand the client_token to the Web SDK. This ten-line script-tag integration is the day-one path — no install required:

    <script src="https://app.personablocks.io/sdk/v1.js"></script>
    <script>
    const pb = PersonaBlocks.create({
    clientToken: 'pbvs_...', // minted server-side via POST /v1/verification-sessions
    flow: 'auto', // 'auto' | 'wallet' | 'phone'
    onComplete: ({ sessionId, vicId, method }) => {
    // IDs only — verdict/tier data is a server-to-server (webhook) concern.
    },
    onError: ({ type, recoverable, message }) => {},
    });
    pb.open();
    </script>

    In test mode there’s a Simulated wallet button and a phone path that accepts the fixed code — no MetaMask and no SMS. About five seconds after the session opens (the default test_delay_seconds is 5), the simulator drives it to your chosen test_outcome, onComplete fires with the IDs, and a signed verification_session.completed webhook arrives at the endpoint you registered in step 2.

  5. Go live.

    Once you’ve driven a session to completion in the sandbox, run the go-live review. When every mandatory check passes you can mint a pb_sk_live_ key from the same Developers tab and point the identical integration at real traffic.