Skip to main content

Polling vs. Webhooks

For both Credential Factory and Verification Gateway, the completion of a flow — credential claimed, verification completed — is asynchronous: it happens whenever the holder gets around to scanning and consenting. There are two ways to find out.

Polling (always available)​

Call GET /api/v1/iaas/credential-offers/{offerId} or GET /api/v1/verifier/sessions/{sessionId} on an interval:

  • Interval: every 3–5 seconds. Faster gains nothing perceptible; slower makes the UI feel laggy after the holder acts.
  • Stop conditions: for Credential Factory, when the credential is issued (claimedAt is present, with status claimed or accepted) or the offer ends (rejected, expired or revoked) — see Get Offer Status; for Verification Gateway, completed / failed. Or the expiresAt timestamp passing while the status is still pending. After expiresAt, stop polling and treat the flow as expired — don't poll a dead resource forever.
  • On expiry: create a new offer/session. Expired resources can return 410 and never come back to life.

A robust polling loop:

async function pollSession(sessionId, expiresAt) {
while (Date.now() < new Date(expiresAt).getTime()) {
const session = await getSession(sessionId);
if (session.status !== 'pending') return session; // terminal
await sleep(4000);
}
return {status: 'failed', failureReason: 'expired'};
}

Pros: trivial to implement, works everywhere, no inbound endpoint to secure. Cons: a few seconds of latency; wasted requests while the holder is deciding.

Webhooks (if configured)​

If webhooks are configured for your account, iDen2 delivers a callback to your endpoint when a session reaches a terminal state. Webhook configuration is account-specific and managed by the iDen2 team outside the API — contact support to set it up.

Two VerificationSession fields help you monitor delivery:

FieldMeaning
callbackDeliveredAtWhen your webhook was successfully notified
callbackAttemptsNumber of delivery attempts (>1 means your endpoint failed at least once)
callbackDeliveryStatuspending, delivered, or exhausted — independent of verification status

A session can be completed with callbackDeliveryStatus: "exhausted" when verification succeeded but your webhook endpoint stayed unreachable. This is not a failureReason — monitor callbackDeliveryStatus and confirm results via GET /sessions/{sessionId}.

Never trust the callback alone

Always validate the callback payload, and confirm the result via GET /sessions/{sessionId} before granting access. An inbound HTTP request is unauthenticated input — the status endpoint, called with your own credentials, is the source of truth.

Pros: near-instant notification, no polling traffic. Cons: you must run a reachable, secured endpoint; you still need the confirmation GET; delivery can fail.

Which should you use?​

SituationRecommendation
Getting started, prototypingPolling
Interactive UI where a user is waitingPolling (simple) or webhooks + confirmation GET (snappier)
Long-TTL or unattended flowsWebhooks, with polling as fallback near expiresAt
Strict infrastructure constraints (no inbound traffic)Polling

The patterns compose: use webhooks as the fast path and a slow poll (or a single check at expiresAt) as the safety net.