Issuer integration

You have an existing identity verification flow (DigiD, BankID, OIDC, your own KYC) and want to mint OwlID credentials for verified users.

Setup

bun add @owlid/sdk
import { OwlIssuer } from '@owlid/sdk'

const issuer = new OwlIssuer({ apiKey: process.env.OWLID_API_KEY! })

Issuance flow

Code

// 1. Open a session
const session = await issuer.startSession('didit')
// session.start tells you what to render:
//   { type: 'form', fields: [...] }
//   { type: 'redirect', url, relayState? }
//   { type: 'qr', qrData, orderRef, autoStartUrl? }
//   { type: 'webhook', url }

// 2. Drive the provider flow.
//    For form-based providers, submit the verified claims directly:
await issuer.submitClaims(session.id, {
  firstName: 'Jan',
  lastName: 'de Vries',
  dateOfBirth: '1985-03-15',
  nationality: 'NL',
})

// 3. Issue — bound to the holder's public key.
const issued = await issuer.issue(session.id, {
  publicKey: holderPublicKey,
  algorithm: 'p256', // 'p256' for WebAuthn passkeys, 'ed25519' for raw keys
})

// issued.document — ProofDocument JSON, send to the holder app.

The platform does not retain the unhashed claims past the session TTL. Once issued, only the signed Merkle root and audit-event hashes remain.

Provider flow types

start.typeMeaningWhat you render
formForm-based providersRender start.fields
redirectOIDC / SAML redirectNavigate to start.url
qrQR-based mobile-app providers (e.g. BankID)Render start.qrData
webhookAsync KYC providers (e.g. Didit, Onfido)Send user to start.url

Polling async sessions

For QR or webhook flows, poll until the session reaches verified:

let snapshot = await issuer.poll(session.id)
while (snapshot.status === 'pending') {
  await new Promise((r) => setTimeout(r, 1500))
  snapshot = await issuer.poll(session.id)
}
if (snapshot.status === 'verified') {
  const issued = await issuer.issue(session.id, { publicKey, algorithm: 'p256' })
}

Issuer key management

Your account's signing key is generated by OwlID on signup and registered automatically with the on-chain IssuerRegistry. Verifiers connecting to OwlID trust your credentials with no per-customer setup.

Reference