---
title: Security
description: How to validate and secure IDCloud webhook payloads — signature verification and best practices.
canonical: https://developer.unico.io/dual-api/developers/webhooks-and-events/security
locale: en
generated_by: markdown-export
---

Webhook reliability depends as much on your endpoint's behavior as on Unico's delivery guarantees. This page covers the three invariants your endpoint must respect: **idempotency**, **concurrency limit**, and **error rate**.

### Idempotency

Unico's webhook implementation guarantees **at-least-once delivery** — the same status may be notified more than once for the same `processId`. Your endpoint **must** be idempotent.

Recommended pattern:

1. On every webhook call, first check whether `processId` has already been processed.
2. If it has, return `2xx` immediately (the work is already done).
3. If not, apply your business logic and persist the fact that this `processId` was processed.

```javascript
// pseudo-code
async function handleWebhook(req, res) {
  const { processId } = req.body;

  if (await alreadyProcessed(processId)) {
    return res.status(200).end();
  }

  await applyBusinessLogic(req.body);
  await markAsProcessed(processId);
  return res.status(200).end();
}
```

:::warning[Why this matters]
A non-idempotent endpoint that runs business logic on every delivery (e.g., charges a card, sends an email) will multi-fire when a retry happens — and retries are normal, not exceptional, in webhook delivery.
:::

### Concurrency limit

To protect your endpoint from spikes during high-volume periods, configure a maximum number of simultaneous in-flight deliveries (max: **500**) when registering the webhook.

When the concurrency limit is reached, Unico queues additional deliveries and processes them as capacity becomes available. Combined with retries, this means a sustained spike can extend the effective delivery time of new webhooks.

### Error rate

The error rate (responses outside the `200`–`299` range) should always be low. If your endpoint starts returning errors at scale, Unico **automatically reduces the webhook throughput** for that endpoint. Combined with the retry mechanism, this can significantly increase the execution time of new webhooks.

Operational guidance:

- Monitor non-2xx responses on your side. Alert on sustained error rates above your normal baseline.
- Treat your webhook handler as a **critical path** — it should be one of the most reliable services in your stack.
- **For planned maintenance**, prefer stopping intake at the load balancer rather than returning `503`. Sustained non-2xx responses — including `503` — activate the automatic throughput throttling described above; when your endpoint recovers, the reduced throughput delays delivery of events that queued up during the outage. Do not return `200` for unprocessed events.

### Status semantics

Treat the set of `state` and `lastEvent` values as evolvable configuration:

- React only to states / events you explicitly handle.
- Log unknown values — do not error out on them.
- New states may be added without a major version change.