Get started

10-minute quick start

Create a test session, complete it with sandbox values and receive the webhook.

View as Markdown

You need a dashboard account, a published workflow (the default KYC workflow is fine) and a test key. No account yet? Request access — once your request is approved, you get an email with a link to create your account, and you start in test mode.

Get a test key and a workflow id

In the dashboard open Developers → API keys and create a key in test mode (sk_test_…). Copy the id of a published workflow from Workflows (wf_…).

Create a session

curl https://api.okyc.stream/v1/sessions \
  -H "Authorization: Bearer $OKYC_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: signup-user_123" \
  -d '{ "workflow_id": "wf_…", "reference_id": "user_123" }'

The response contains the session id, its status (created), the hosted flow url, a client_token and expires_at. With Node, the same call through @okyc/node:

server.mjs
// Your frontend calls this, then passes { clientToken, sessionUrl } to @okyc/web or @okyc/react.
app.post('/api/kyc/session', express.json(), async (req, res) => {
  const userId = req.header('x-user-id') ?? 'demo-user'; // use your own auth here
  try {
    const session = await okyc.sessions.create(
      {
        workflowId: process.env.OKYC_WORKFLOW_ID,
        referenceId: userId,
        redirectUrl: process.env.REDIRECT_URL,
      },
      { idempotencyKey: `kyc-${userId}-${new Date().toISOString().slice(0, 10)}` },
    );
    res.json({ clientToken: session.clientToken, sessionUrl: session.url });
  } catch (e) {
    res.status(e.statusCode ?? 500).json({ error: e.code ?? 'error' });
  }
});

Open the flow

Paste the url in a browser (or pass it to a web or mobile SDK). Complete it with test data: every step offers Use test data, and the OTP is 123456.

Receive the webhook

Add an endpoint under Developers → Webhooks (test mode) and copy its signing secret (whsec_…). For local development, expose your server with a tunnel. Verify every delivery:

server.mjs
// Webhooks: verify against the RAW body, dedupe on event.id, then fetch details from the API.
const seen = new Set();
app.post('/okyc/webhook', express.raw({ type: 'application/json' }), async (req, res) => {
  let event;
  try {
    event = await okyc.webhooks.constructEvent(
      req.body,
      req.header('okyc-signature'),
      process.env.OKYC_WEBHOOK_SECRET,
    );
  } catch {
    return res.sendStatus(400);
  }
  if (seen.has(event.id)) return res.sendStatus(200);
  seen.add(event.id);
  if (event.type === 'session.approved' || event.type === 'session.declined') {
    const session = await okyc.sessions.retrieve(event.data.session.id);
    console.log(`user ${session.reference_id} → ${session.status}`);
    // mark the user verified / rejected in your database
  }
  res.sendStatus(200);
});

A passing test session sends session.created, session.started, session.processing and finally session.approved (to endpoints subscribed to those events).

Fetch the result

curl https://api.okyc.stream/v1/sessions/ses_…?expand=checks \
  -H "Authorization: Bearer $OKYC_SECRET_KEY"

Next: sessions, webhooks, or a mobile SDK.

On this page