> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zenoo.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Go-Live Checklist

> 12-item pre-production checklist covering credentials, security, resilience, result handling, and monitoring.

# Go-Live Checklist

Complete every item before switching from staging to production. Each item addresses a specific failure mode observed in real integrations.

<Warning>Do not go live until every item on this checklist is verified. Skipping items leads to production incidents that are entirely preventable.</Warning>

## 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.

```bash theme={null}
# 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.

```bash theme={null}
# 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.

<Note>Staging and production webhooks use different secrets. Update the secret in your configuration.</Note>

## 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.

```javascript theme={null}
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.

```javascript theme={null}
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

<Tip>Include `external_reference` on every verification request. This prevents duplicate verifications caused by retries, user double-clicks, or race conditions.</Tip>

```json theme={null}
{
  "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:

| Verdict | Required action                               |
| ------- | --------------------------------------------- |
| `Pass`  | Proceed with onboarding or approval           |
| `Refer` | Route to manual compliance review             |
| `Fail`  | Block onboarding, escalate to compliance team |

<Warning>Do not assume all results will be `Pass`. Test your `Refer` and `Fail` code paths with the [staging test data](/testing/test-data).</Warning>

### 8. Handle webhook edge cases

Your webhook handler must process all five event types, not just `verification.completed`:

| Event                    | Required action                               |
| ------------------------ | --------------------------------------------- |
| `verification.completed` | Process results, update customer record       |
| `screening.completed`    | Review matches, update risk profile           |
| `journey.abandoned`      | Send reminder or create a new journey         |
| `journey.expired`        | Create a new verification journey             |
| `check.failed`           | Alert compliance team for manual intervention |

<Warning>Ignoring `journey.abandoned` or `journey.expired` events causes customers to get stuck in your onboarding flow.</Warning>

### 9. Implement webhook deduplication

Zenoo may deliver the same webhook more than once. Your handler must be idempotent.

```javascript theme={null}
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:

| Metric                       | Alert 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 rate           | Sudden 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

<Check>
  Complete all 12 items before going live. Each item addresses a real production failure mode.
</Check>

| #  | Item                                                      | Status |
| -- | --------------------------------------------------------- | ------ |
| 1  | Replace staging API key with production key               | \[ ]   |
| 2  | Update base URL to production                             | \[ ]   |
| 3  | Update webhook endpoint to production URL                 | \[ ]   |
| 4  | Verify webhook signature validation works                 | \[ ]   |
| 5  | Implement exponential backoff retry logic                 | \[ ]   |
| 6  | Set up idempotency with external\_reference               | \[ ]   |
| 7  | Handle all verdict outcomes (Pass, Refer, Fail)           | \[ ]   |
| 8  | Handle webhook edge cases (abandoned, expired, failed)    | \[ ]   |
| 9  | Implement webhook deduplication                           | \[ ]   |
| 10 | Set up monitoring (error rates, webhooks, response times) | \[ ]   |
| 11 | Test one real verification in production                  | \[ ]   |
| 12 | Configure alerts for 5xx spikes and webhook failures      | \[ ]   |

## Next steps

* [Error Handling](/guides/error-handling) -- Retry strategies and circuit breaker behavior
* [Webhooks Guide](/guides/webhooks) -- Webhook event types and delivery
* [Reference: Error Codes](/reference/error-codes) -- Complete error code reference
