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

# Webhooks

> Receive signed payout lifecycle events and process retries safely.

COP By sends outbound webhook events when a BRE-B payout changes state. Configure the endpoint and
signing secret in the partner dashboard.

## Verify every request

Read the raw body before parsing JSON and calculate:

```text theme={null}
HMAC-SHA256(secret, timestamp + "." + rawBody)
```

Compare the hex digest with `X-CopBy-Signature` using a constant-time comparison. Also read:

| Header               | Purpose                  |
| -------------------- | ------------------------ |
| `X-CopBy-Timestamp`  | Signature timestamp      |
| `X-CopBy-Event-Id`   | Stable deduplication key |
| `X-CopBy-Event-Type` | Payout lifecycle event   |

Reject an invalid signature before processing the payload.

## Return quickly

Persist the event ID, enqueue your work, and return `2xx`. Duplicate event IDs must return success
without applying the event twice.

COP By retries failed deliveries after approximately 1 minute, 5 minutes, 30 minutes, 2 hours, and
12 hours.

## Reconcile

Webhooks can arrive late or more than once. Poll `GET /api/integrations/breb/payouts/{payoutId}` as a
fallback and use the current payout resource to resolve discrepancies.

<Note>
  `/api/breb/webhook` is the inbound Bridge-to-COP-By endpoint. Partners should not call it. Your
  integration receives the outbound `partnerPayoutStatus` webhook documented in API Reference.
</Note>

<Columns cols={2}>
  <Card title="BRE-B payouts" icon="building-columns" href="/breb-payouts">
    Review the payout flow that produces these events.
  </Card>

  <Card title="Errors and lifecycle" icon="triangle-exclamation" href="/errors-lifecycle">
    Handle terminal, recoverable, and idempotent outcomes.
  </Card>
</Columns>
