Skip to main content

Go-Live Checklist

Complete every item before switching from staging to production. Each item addresses a specific failure mode observed in real integrations.
Do not go live until every item on this checklist is verified. Skipping items leads to production incidents that are entirely preventable.

Credentials and endpoints

1. Replace staging API key with production key

Update your environment configuration to use the production API key. Staging keys do not work against the production URL.
# Before (staging)
ZENOO_API_KEY=stg_your_staging_key

# After (production)
ZENOO_API_KEY=prod_your_production_key

2. Update base URL to production

Switch from the staging URL to the production URL. This must change everywhere your application makes Zenoo API calls.
# Before (staging)
ZENOO_BASE_URL=https://instance.staging.onboardapp.io

# After (production)
ZENOO_BASE_URL=https://instance.prod.onboardapp.io

3. Update webhook endpoint to production URL

Point Zenoo at your production webhook endpoint. Contact your Zenoo account manager to update the webhook URL, or configure it in the Zenoo dashboard.
Staging and production webhooks use different secrets. Update the secret in your configuration.

Security

4. Verify webhook signature validation works

Confirm that your webhook handler validates the X-Zenoo-Signature header on every request. Test by sending a webhook with a tampered payload and verifying that your handler rejects it.
const crypto = require("crypto");

function verifySignature(rawBody, signature, secret) {
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

// Reject unverified webhooks
if (
  !verifySignature(rawBody, req.headers["x-zenoo-signature"], webhookSecret)
) {
  return res.status(401).json({ error: "Invalid signature" });
}

Resilience

5. Implement exponential backoff retry logic

Your API client should retry 5xx errors and timeouts with increasing delays. Never retry 4xx errors without fixing the request.
const RETRY_DELAYS = [0, 5000, 25000, 60000]; // 4 attempts max

async function callZenoo(requestFn) {
  for (let attempt = 0; attempt < RETRY_DELAYS.length; attempt++) {
    if (attempt > 0) await sleep(RETRY_DELAYS[attempt]);

    const response = await requestFn();

    if (response.status === 429) {
      const retryAfter = parseInt(response.headers.get("Retry-After") || "60");
      await sleep(retryAfter * 1000);
      continue;
    }

    if (response.status >= 500 && attempt < RETRY_DELAYS.length - 1) {
      continue;
    }

    return response;
  }
}

6. Set up idempotency with external_reference

Include external_reference on every verification request. This prevents duplicate verifications caused by retries, user double-clicks, or race conditions.
{
  "company_name": "Acme Holdings Ltd",
  "registration_number": "12345678",
  "country": "GB",
  "external_reference": "your-unique-internal-id-here"
}
Use a stable, unique identifier from your system: application ID, customer reference, or order number. If the same external_reference is submitted twice, Zenoo returns the existing case.

Result handling

7. Handle all verdict outcomes

Your application must handle all three overall_verdict values. Verify your decision logic:
VerdictRequired action
PassProceed with onboarding or approval
ReferRoute to manual compliance review
FailBlock onboarding, escalate to compliance team
Do not assume all results will be Pass. Test your Refer and Fail code paths with the staging test data.

8. Handle webhook edge cases

Your webhook handler must process all five event types, not just verification.completed:
EventRequired action
verification.completedProcess results, update customer record
screening.completedReview matches, update risk profile
journey.abandonedSend reminder or create a new journey
journey.expiredCreate a new verification journey
check.failedAlert compliance team for manual intervention
Ignoring journey.abandoned or journey.expired events causes customers to get stuck in your onboarding flow.

9. Implement webhook deduplication

Zenoo may deliver the same webhook more than once. Your handler must be idempotent.
app.post("/webhooks/zenoo", async (req, res) => {
  const { journey_id, event_type } = req.body;

  // Check for duplicate delivery
  const existing = await db.webhookEvents.findOne({ journey_id, event_type });
  if (existing) {
    return res.status(200).json({ received: true });
  }

  // Store before processing to prevent race conditions
  await db.webhookEvents.create({ journey_id, event_type, payload: req.body });
  await processEvent(req.body);

  res.status(200).json({ received: true });
});
Always return 200 for duplicates to prevent unnecessary retries.

Monitoring

10. Set up monitoring

Track these metrics from day one:
MetricAlert threshold
API error rate (5xx)> 5% over 10 minutes
Webhook delivery failures> 3 consecutive failures
Average response time> 30 seconds (sync mode)
Verification completion rate< 90% over 1 hour
Sanctions hit rateSudden spike (> 2x normal)
Use the request_id from error responses to correlate application logs with Zenoo server logs.

11. Test one real verification in production

After completing items 1-10, run a single real verification in production. Use a real company or individual (not test data). Confirm:
  • API call succeeds with 200 response
  • Response contains valid overall_verdict and risk_tier
  • Webhook is delivered to your production endpoint
  • Webhook signature verifies correctly
  • Your application processes the result correctly

12. Configure alerts for failures

Set up automated alerts for:
  • 5xx error spikes from the Zenoo API. These indicate server-side issues, contact Zenoo support.
  • Webhook delivery failures. If your endpoint returns non-2xx for more than 3 consecutive webhooks, investigate immediately.
  • Verification timeout increases. A sustained increase in response times may indicate provider degradation.
  • Unusual verdict distributions. A sudden spike in Fail verdicts may indicate a configuration issue, not actual compliance failures.

Summary

Complete all 12 items before going live. Each item addresses a real production failure mode.
#ItemStatus
1Replace staging API key with production key[ ]
2Update base URL to production[ ]
3Update webhook endpoint to production URL[ ]
4Verify webhook signature validation works[ ]
5Implement exponential backoff retry logic[ ]
6Set up idempotency with external_reference[ ]
7Handle all verdict outcomes (Pass, Refer, Fail)[ ]
8Handle webhook edge cases (abandoned, expired, failed)[ ]
9Implement webhook deduplication[ ]
10Set up monitoring (error rates, webhooks, response times)[ ]
11Test one real verification in production[ ]
12Configure alerts for 5xx spikes and webhook failures[ ]

Next steps