Skip to main content

Result Delivery

Zenoo supports three methods for delivering verification results. Choose based on your infrastructure, latency requirements, and integration complexity.

Pull via Token

The simplest approach. After initiating a verification, poll the pull endpoint until results are ready.How it works:
  1. Initiate a verification (sync or async). Save the pull token from the response.
  2. Poll GET /sharable-payload/{pull_token} at intervals.
  3. When results are ready, the endpoint returns 200 with the full payload.

Polling Strategy

Time WindowPoll IntervalRationale
0 to 2 minutesEvery 10 secondsMost automated checks (screening, registry) complete in this window
2 to 10 minutesEvery 30 secondsAllows for slower providers or queued checks
After 10 minutesStop pollingSwitch to webhook or contact support
poll-results.js
async function pollResults(pullToken) {
  const maxAttempts = 30;

  for (let i = 0; i < maxAttempts; i++) {
    const response = await fetch(
      `https://instance.prod.onboardapp.io/api/gateway/sharable-payload/${pullToken}`
    );

    if (response.status === 200) return await response.json();
    if (response.status === 404) throw new Error("Token invalid or expired");

    // 204: still processing
    const delay = i < 12 ? 10_000 : 30_000;
    await new Promise((r) => setTimeout(r, delay));
  }

  throw new Error("Polling timeout. Results not ready after 10 minutes.");
}

Pull Endpoint Response Codes

StatusMeaning
200Results are ready. Response body contains the full verification payload.
204Still processing. Retry after a short delay.
404Token is invalid or has expired.

Pull Token Lifetime

Pull tokens remain valid for 30 days after results become available. After that, the token expires and returns 404. Store results in your own system before the token expires.

Comparison

AspectPull via TokenWebhook PushPing + Pull
MechanismPoll endpoint at intervalsFull results pushed to your endpointLightweight notification, you fetch results
LatencyDepends on poll interval (10-30s)Near-instantNear-instant notification, you control fetch timing
ComplexityLowestMedium (webhook endpoint + sig verification)Medium (webhook + pull call)
ReliabilityHigh (you control timing)Depends on webhook deliveryHigh (notification + guaranteed pull)
Payload sizeN/A (you fetch on demand)Full results in webhookSmall notification, full results on pull
Best forPOC, low-volume, simple integrationsReal-time processing, event-driven architecturesProduction systems, high-reliability requirements

Recommendation

For production, use Ping + Pull. You get real-time notification that results are available, with the flexibility to fetch full results on your own schedule. Small webhook payloads are more reliable to deliver, and you always have the pull endpoint as a fallback.
For POC and development: Use Pull via Token. It requires no webhook infrastructure. Just initiate a verification and poll for results. For event-driven architectures: Use Webhook Push. If your system is already built around event processing (message queues, serverless functions), receiving full results via webhook fits naturally.

Combining Methods

The most resilient pattern uses webhooks with polling as a fallback:
  1. Configure webhooks for instant notification (push or ping+pull).
  2. Implement a background job that polls for any verifications that have been pending longer than expected.
  3. If a webhook is missed (endpoint down, network issue), the polling job catches it.
fallback-poller.js
// Background job: catch any missed webhooks
async function checkPendingVerifications() {
  const pending = await db.verifications.find({
    status: "pending",
    initiated_at: { $lt: new Date(Date.now() - 10 * 60 * 1000) } // >10 min ago
  });

  for (const v of pending) {
    const response = await fetch(
      `https://instance.prod.onboardapp.io/api/gateway/sharable-payload/${v.pull_token}`
    );
    if (response.status === 200) {
      const results = await response.json();
      await processResults(v.id, results);
    }
  }
}

Next Steps