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

# Corridor Webhooks API: Circle Payment Status Events

> Reference for POST /webhooks/circle — how Meterlane receives signed Circle payment events and maps them to corridor payment statuses.

Meterlane uses a single webhook endpoint to receive payment lifecycle events from Circle's Cross-Platform Network. When Circle processes a payout you initiated via `POST /corridors/:id/pay`, it posts a signed event payload to this URL, and Meterlane updates the corresponding payment record's status in real time. You do not call this endpoint directly — instead, you register it as the webhook destination inside your Circle dashboard and let Circle drive the updates.

***

## POST /webhooks/circle

Receives inbound payment event notifications from Circle. Meterlane verifies the `Circle-Signature` HMAC on every request before processing it; unauthenticated or tampered requests are rejected immediately.

<Note>
  Register `https://corridor.meterlane.app/webhooks/circle` as the webhook destination URL in your Circle dashboard. Circle will POST signed event payloads to this address whenever a payment status changes.
</Note>

<ParamField header="Circle-Signature" type="string" required>
  HMAC SHA-256 signature generated by Circle using your shared webhook secret. Meterlane validates this signature on every inbound request. Requests with missing or invalid signatures return `401 Unauthorized`.
</ParamField>

### Payment events

| Circle Event                 | Corridor Payment Status | Meaning                                                     |
| ---------------------------- | ----------------------- | ----------------------------------------------------------- |
| `payments.payment_completed` | `SETTLED`               | Funds have been delivered to the beneficiary's bank account |
| `payments.payment_failed`    | `FAILED`                | The payout was rejected or could not be completed           |
| `payments.compliance_hold`   | `COMPLIANCE_HOLD`       | Payment is paused pending a compliance review               |

### Example webhook payload

Circle posts a JSON body to this endpoint. The `type` field identifies the event and the nested `payment` object carries the `id` that maps to a `cpnPaymentId` in Meterlane.

```json theme={null}
{
  "clientId": "circle-client-id",
  "notificationType": "payments",
  "version": 1,
  "customAttributes": {
    "clientId": "circle-client-id"
  },
  "payment": {
    "id": "cpn_a1b2c3d4e5f6g7h8i9j0",
    "type": "payment",
    "status": "paid",
    "amount": {
      "amount": "100.00",
      "currency": "USD"
    },
    "updateDate": "2025-01-15T14:35:22Z"
  },
  "type": "payments.payment_completed"
}
```

<Note>
  Meterlane handles all signature verification automatically. You do not need to implement any verification logic on your end — simply ensure the `Circle-Signature` header is forwarded untouched if you are proxying Circle events through your own infrastructure.
</Note>

<Warning>
  A `payments.compliance_hold` event means the payment is **paused**, not permanently failed. The beneficiary has not received funds yet, and the payment may still settle or be rejected after Circle's compliance review completes. Do not treat `COMPLIANCE_HOLD` as a terminal state — wait for a subsequent `payments.payment_completed` or `payments.payment_failed` event before reconciling the transaction.
</Warning>
