# Receive credit webhook events

React to allowance and credit-capacity changes in an approved preview environment. You need a registered webhook endpoint and confirmation that credit events are enabled for your workspace.

> **Preview**
>
> Confirm credit-event availability and the environment contract with Complyance before using these events for customer or production operations. See the [credit API restriction](https://docs.complyance.io/api-reference/connect/credits/).

## Events

| Event | Meaning |
| - | - |
| `isv.credits.allowance.changed` | A current or scheduled allowance changed |
| `isv.credits.allowance.paused` | The current allowance was paused |
| `isv.credits.allowance.resumed` | The current allowance was resumed |
| `isv.credits.allowance.expired` | The allowance period ended |
| `isv.credits.company.threshold` | Committed company usage crossed 80% of its allowance |
| `isv.credits.company.exhausted` | Company allowance availability reached zero |
| `isv.credits.pool.low` | Pool availability crossed 20% or 10% remaining |
| `isv.credits.pool.exhausted` | Pool availability reached zero |
| `isv.credits.consumption.reversed` | Finalized consumption was reversed |
| `isv.credits.bulk.completed` | A bulk allowance job finished, possibly with row errors |

Committed usage includes finalized usage and active reservations. The 20% and 10% pool notifications are distinct events; do not combine their identifiers.

## Read the payload

```json title="Example pool threshold event"
{
  "eventId": "isv-credit:example-pool-threshold-20",
  "data": {
    "id": "isv-credit:example-pool-threshold-20",
    "type": "isv.credits.pool.low",
    "timestamp": "2026-09-22T10:00:00.000Z",
    "data": {
      "schemaVersion": "1.0",
      "triggeringCompanyId": "66b9f0a1c2d3e4f567890123",
      "reservationId": "example-reservation-142",
      "totalCredits": 10000,
      "availableCredits": 1900,
      "percentageAvailable": 19,
      "thresholdPercent": 20,
      "amount": 25
    }
  }
}
```

The event-specific payload is inside `data.data`. `schemaVersion` identifies its version; ignore unknown optional fields.

The fields inside `data.data` depend on the event. Every payload has `schemaVersion`. Optional fields are marked; they can be missing.

### Allowance events

`isv.credits.allowance.changed`, `.paused`, `.resumed` and `.expired`.

| Field | Meaning |
| - | - |
| `companyId` | The company whose allowance changed |
| `action` | What happened. See the list below. |
| `allowance` | The allowance after the change. See the next table. |
| `reason` | The reason recorded with the change |
| `bulkJobId` | Optional. The bulk job that made the change, if one did. |

| `allowance` field | Meaning |
| - | - |
| `target` | `current` or `scheduled` |
| `limit` | The allowance limit in credits |
| `periodType` | `monthly`, `annual` or `custom` |
| `allowancePeriodId` | Optional. The allowance period |
| `startAt`, `endAt` | When the period starts, and the moment just after it ends |
| `status` | `active`, `paused`, `scheduled`, `cancelled` or `expired` |
| `version` | Increases with every change. Use it to ignore an older event that arrives late. |
| `finalizedUsage`, `reserved` | Optional. Credits used so far and credits held for submissions in progress |

`action` is one of:

| Event | `action` values |
| - | - |
| `isv.credits.allowance.changed` | `current.created`, `current.replaced`, `current.paused`, `current.resumed`, `scheduled.created`, `scheduled.replaced`, `scheduled.cancelled`, `scheduled.activated` |
| `isv.credits.allowance.paused` | `current.paused` |
| `isv.credits.allowance.resumed` | `current.resumed` |
| `isv.credits.allowance.expired` | `current.expired`, `scheduled.expired` |

Pausing or resuming sends two events: the specific one and `isv.credits.allowance.changed`. Handle them so that the second one changes nothing.

```json title="Example allowance replaced event (data.data)"
{
  "schemaVersion": "1.0",
  "companyId": "66b9f0a1c2d3e4f567890123",
  "action": "current.replaced",
  "allowance": {
    "target": "current",
    "limit": 5000,
    "periodType": "monthly",
    "allowancePeriodId": "example-period-2026-10",
    "startAt": "2026-10-01T00:00:00.000Z",
    "endAt": "2026-11-01T00:00:00.000Z",
    "status": "active",
    "version": 4
  },
  "reason": "Raised for October volume"
}
```

### Company capacity events

`isv.credits.company.threshold` and `isv.credits.company.exhausted`.

| Field | Meaning |
| - | - |
| `companyId` | The company |
| `allowancePeriodId` | The allowance period |
| `reservationId` | The reservation that crossed the threshold |
| `limit` | The allowance limit |
| `finalizedUsage` | Credits used |
| `reserved` | Credits held for submissions in progress |
| `committedUsage` | `finalizedUsage` plus `reserved` |
| `available` | Credits left in the allowance |
| `percentageUsed` | `committedUsage` as a percentage of `limit` |
| `thresholdPercent` | `80`. Threshold event only. |
| `amount` | The credits the triggering reservation held |

### Pool events

`isv.credits.pool.low` and `isv.credits.pool.exhausted`. The example above is a pool event.

| Field | Meaning |
| - | - |
| `triggeringCompanyId` | Optional. The company whose usage crossed the level |
| `reservationId` | Optional. The reservation that crossed it |
| `totalCredits` | Credits in the pool |
| `availableCredits` | Credits not used or held |
| `percentageAvailable` | `availableCredits` as a percentage of `totalCredits` |
| `thresholdPercent` | `20` or `10`. Low event only. |
| `amount` | The credits the triggering reservation held |

### Consumption reversed

`isv.credits.consumption.reversed`.

| Field | Meaning |
| - | - |
| `companyId` | The company |
| `reservationId`, `transactionId` | The reversal |
| `originalTransactionId` | The consumption that was reversed |
| `allowancePeriodId` | The allowance period the credits return to |
| `amount` | Credits returned |
| `reason` | Why the consumption was reversed |
| `restorePool` | `true` when the credits also return to the pool |
| `countryCode`, `documentType` | The document the consumption was for |
| `balanceBefore`, `balanceAfter` | `companyAvailable` and `poolAvailable` before and after the reversal |

```json title="Example consumption reversed event (data.data)"
{
  "schemaVersion": "1.0",
  "companyId": "66b9f0a1c2d3e4f567890123",
  "reservationId": "example-reservation-143",
  "transactionId": "example-transaction-981",
  "originalTransactionId": "example-transaction-977",
  "allowancePeriodId": "example-period-2026-10",
  "amount": 12,
  "reason": "Submission did not complete",
  "restorePool": true,
  "countryCode": "AE",
  "documentType": "tax_invoice",
  "balanceBefore": { "companyAvailable": 488, "poolAvailable": 1888 },
  "balanceAfter": { "companyAvailable": 500, "poolAvailable": 1900 }
}
```

### Bulk completed

`isv.credits.bulk.completed`.

| Field | Meaning |
| - | - |
| `jobId` | The bulk allowance job |
| `status` | `completed`, or `completed_with_errors` when some rows failed |
| `totals` | `total`, `processed`, `succeeded` and `failed` row counts |
| `completedAt` | When the job finished |

Retrieve the job to see which rows failed and why.

## Who can subscribe

Owners, Admins and Partners can create, change and delete webhook subscriptions, including those for credit events. Other roles get `You do not have permission to perform this action`. In the event picker, credit events are under **ISV Credit Management**. See [Set up a webhook](https://docs.complyance.io/one-platform/developer-portal/webhooks/setup/).

## Handle delivery safely

Follow the shared [signature verification and delivery guide](https://docs.complyance.io/one-platform/developer-portal/webhooks/payload-and-delivery/). Verify the signature using the raw request body, store the event durably, and acknowledge with `2xx` before doing slow work.

Deduplicate using `eventId`, also sent in `X-Webhook-ID`. Repeated delivery must not repeat a customer notification or change your recorded balance twice. Events can arrive out of order; compare timestamps and allowance versions before replacing newer state.

## Reconcile missed events

Use transaction reads or a credit export to reconcile activity in the confirmed environment. There is no partner-facing event replay API. A webhook delivery issue does not justify applying a new allowance change to recreate an event.

Next, use the [credit API preview](https://docs.complyance.io/api-reference/connect/credits/) to read the relevant company or bulk job.

Source: https://docs.complyance.io/partner-platform/isv/credit-webhooks/
