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

# Webhooks

In order to notify your system of asynchronous actions within the Orb platform, Orb provides a powerful, real-time webhooks system that can issue calls to an endpoint of your choosing when certain events take place. Webhooks allow your system or integration to take actions as a result of these events.

Orb's supported webhook events can be useful for a wide variety of use cases:

1. **Resource lifecycle changes**: Set up entitlements in your service as a result of object creation, such as a `subscription.created` event.
2. **Balance events**: Send out an end-user email when a customer's pre-paid credit balance is nearing zero.
3. **Data exports**: Receive events when an export of resource data to a destination succeeds or fails.

<Note>
  Delivery of Resource lifecycle changes webhooks typically occurs in near real-time, though occasional delays may occur.

  For alerts on usage, cost, and credit balance, we evaluate alerts (and therefore issue webhooks) several times a day, but the latency guarantee will be a function of your workload. This can be reduced with provisioning for customers on Growth and Enterprise plans.
</Note>

Webhooks payloads in Orb follow the format:

```json theme={null}
{
    // Unique to this WebhookEvent resource, and can be used for idempotency (process-once) purposes
    "id": string,
    // ISO8601 `created_at` timestamp of the `WebhookEvent` resource
    "created_at": string,
    // Identifies the type of webhook event being triggered
    "type": string,
    // If a webhook is associated with a resource, the full resource will be serialized
    // in the webhook body.
    "<resource_name>": object,
    // Additional properties specific to this event
    "properties": object,
}
```

## Configuring webhooks

Webhooks are configured to an `HTTPS` URL on your backend server (note that only the `HTTPS` scheme is accepted for the production version of your webhook configuration).

Each webhook endpoint is associated with a *secret* (see the `X-Orb-Signature` clause below). By default, all webhook events are sent to every endpoint.

## Debugging webhooks

In the Orb UI, you can test your webhook configuration to ensure that it's set up properly and ready to receive events from us. From the [webhooks portal](https://app.withorb.com/webhooks), you can select on any webhook endpoint to send a "test event." <img src="https://mintcdn.com/orb-9bba378a/mmAvm-wURvmz4Fz_/images/webhook-test.png?fit=max&auto=format&n=mmAvm-wURvmz4Fz_&q=85&s=559a29ac82b65acfacb14236b97e58ad" alt="Webhook test" width="2018" height="1136" data-path="images/webhook-test.png" />

If you need to manually trigger a webhook event to be sent to your server, you can also resend it in the UI. <img src="https://mintcdn.com/orb-9bba378a/w7VuLoqrCaLK7or4/images/resend-webhook.png?fit=max&auto=format&n=w7VuLoqrCaLK7or4&q=85&s=a97b6b3da60005fabe6f93d41805e7bf" alt="Resend webhook" width="2636" height="1483" data-path="images/resend-webhook.png" />

## Webhooks retries

Orb guarantees *at-least-once* delivery for a single webhook event to each of your endpoint.

Orb expects a `2xx` within five seconds as a successful response to a webhook request. If the request returns an error or otherwise times out, Orb will attempt to retry the event on the following retry schedule, stopping when either retries are exhausted or the request is accepted:

* 5 seconds
* 5 minutes
* 30 minutes
* 2 hours
* 5 hours
* 10 hours
* 10 hours

In order for your system to handle duplicate notifications, we recommend storing the `id` of a webhook event temporarily in the webhook consumer and refusing to re-process an event if the same `id` has already been seen.

## Automatic disabling of failing webhook endpoints

Any webhook endpoints that return a `5XX` HTTP status codes for more than 99% of deliveries over a 7-day period will be disabled automatically by Orb to preserve system stability. These endpoints can be re-enabled in the Orb UI.

## Webhook patterns

Event types follow the pattern `<resource_name>.<verb>`, where `<resource_name>` is the root object that is related to the webhook, and the `<verb>` is the event that has taken place (e.g. `customer.created` is a newly created [Customer](/core-concepts#customer) resource).

By convention, a key in the payload will match the `resource_name` prefix in `type` (e.g. if the `type` is `subscription.action`, the payload will contain the serialized subscription resource under the `subscription` key).

## Webhook Event Types: Resource Lifecycle Changes

Orb currently issues the following webhooks for resource lifecycle changes:

### backfill.reflected

Issued when a [backfill](/api-reference/event/fetch-backfill) is closed and its events have been processed as usage.

| key          | schema                                          |
| ------------ | ----------------------------------------------- |
| `backfill`   | [Backfill](/api-reference/event/fetch-backfill) |
| `properties` | `{}`                                            |

### backfill.reverted

Issued when a [backfill](/api-reference/event/fetch-backfill) is reverted, reversing its effects.

| key          | schema                                          |
| ------------ | ----------------------------------------------- |
| `backfill`   | [Backfill](/api-reference/event/fetch-backfill) |
| `properties` | `{}`                                            |

### billable\_metric.edited

Issued when a billable metric is edited. This webhook is only issued when metadata for the resource changes, as billable metrics are otherwise immutable. The `previous_attributes` object will be present and populated with the previous state of any billable metric attributes that have changed.

| key                                          | schema                                              |
| -------------------------------------------- | --------------------------------------------------- |
| `billable_metric`                            | [Billable metric](/api-reference/metric/get-metric) |
| `properties.previous_attributes.name`        | `string`                                            |
| `properties.previous_attributes.description` | `string`                                            |
| `properties.previous_attributes.metadata`    | `object`                                            |

### credit\_note.issued

Issued when a credit note is created.

| key           | schema                                                      |
| ------------- | ----------------------------------------------------------- |
| `credit_note` | [Credit note](/api-reference/credit-note/fetch-credit-note) |
| `properties`  | `{}`                                                        |

### credit\_note.marked\_as\_void

Issued when a credit note is marked as void.

| key           | schema                                                      |
| ------------- | ----------------------------------------------------------- |
| `credit_note` | [Credit note](/api-reference/credit-note/fetch-credit-note) |
| `properties`  | `{}`                                                        |

### customer.balance\_transaction\_created

Issued when the customer balance changes for an Orb customer. The `balance_transaction` object will be present and populated with the specific entry that modified the balance.

| key                              | schema                                                                   |
| :------------------------------- | :----------------------------------------------------------------------- |
| `customer`                       | [Customer](/api-reference/customer/fetch-customer)                       |
| `properties.balance_transaction` | [Balance transaction](/api-reference/customer/list-balance-transactions) |

### customer.created

Issued when a customer resource is created.

| key          | schema                                             |
| ------------ | -------------------------------------------------- |
| `customer`   | [Customer](/api-reference/customer/fetch-customer) |
| `properties` | `{}`                                               |

### customer.edited

Issued when a customer is edited. The `previous_attributes` object will be present and populated with the previous state of any `Customer` attributes that have changed.

| key                                                  | schema                                             |
| ---------------------------------------------------- | -------------------------------------------------- |
| `customer`                                           | [Customer](/api-reference/customer/fetch-customer) |
| `properties.previous_attributes.payment_provider`    | `string`                                           |
| `properties.previous_attributes.payment_provider_id` | `string`                                           |
| `properties.previous_attributes.auto_collection`     | `boolean`                                          |
| `properties.previous_attributes.email`               | `string`                                           |
| `properties.previous_attributes.name`                | `string`                                           |
| `properties.previous_attributes.email_delivery`      | `boolean`                                          |
| `properties.previous_attributes.metadata`            | `object`                                           |
| `properties.previous_attributes.tax_id`              | [TaxId](/api-reference/customer/fetch-customer)    |
| `properties.previous_attributes.shipping_address`    | [Address](/api-reference/customer/fetch-customer)  |
| `properties.previous_attributes.billing_address`     | [Address](/api-reference/customer/fetch-customer)  |

### invoice.edited

Issued when a draft invoice has been edited via the webapp. The `previous_attributes` object will be present and populated with the previous state of any `Invoice` attributes that have changed.

| key                                         | schema                                                                |
| ------------------------------------------- | --------------------------------------------------------------------- |
| `invoice`                                   | [Invoice](/api-reference/invoice/fetch-invoice)                       |
| `properties.previous_attributes.amount_due` | `string`                                                              |
| `properties.previous_attributes.subtotal`   | `string`                                                              |
| `properties.previous_attributes.total`      | `string`                                                              |
| `properties.previous_attributes.discounts`  | `array` of Discounts                                                  |
| `properties.previous_attributes.minimum`    | [Minimum]()                                                           |
| `properties.previous_attributes.line_items` | `array` of [Invoice Line Items](/api-reference/invoice/fetch-invoice) |
| `properties.previous_attributes.net_terms`  | `int`                                                                 |
| `properties.previous_attributes.due_date`   | `date-time`                                                           |

### invoice.invoice\_date\_elapsed

<Warning>
  Serializing and consuming this webhook can be very expensive in the presence of a large number of subscriptions and is not enabled by default. Please reach out to the Orb team to opt-in to the webhook or discuss the intended workflow.
</Warning>

Issued when the `invoice_date` of an invoice has elapsed.

| key                       | schema                                          |
| ------------------------- | ----------------------------------------------- |
| `invoice`                 | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.invoice_date` | `date-time`                                     |

### invoice.issue\_failed

Issued when an invoice fails to issue.

| key                 | schema                                          |
| ------------------- | ----------------------------------------------- |
| `invoice`           | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.reason` | `string`                                        |

### invoice.issued

Issued when an invoice transitions to the `"issued"` state. `"issued"` invoices are frozen (they cannot be edited, manually or via the API). The `automatically_marked_as_paid` property will be true when the issued invoice's amount due is zero, which results in the invoice status being set to paid.

| key                                       | schema                                          |
| ----------------------------------------- | ----------------------------------------------- |
| `invoice`                                 | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.automatically_marked_as_paid` | `boolean`                                       |

### invoice.manually\_marked\_as\_paid

Issued when an invoice is manually marked as paid.

| key                                | schema                                          |
| ---------------------------------- | ----------------------------------------------- |
| `invoice`                          | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.payment_received_date` | `date-time`                                     |
| `properties.external_id`           | `string`                                        |
| `properties.notes`                 | `string`                                        |

### invoice.manually\_marked\_as\_void

Issued when an invoice is manually marked as void.

| key          | schema                                          |
| ------------ | ----------------------------------------------- |
| `invoice`    | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties` | `{}`                                            |

### invoice.payment\_failed

Issued when automated payment collection for an invoice fails for a configured payment gateway.

| key                                          | schema                                          |
| -------------------------------------------- | ----------------------------------------------- |
| `invoice`                                    | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.payment_provider`                | `"stripe"`                                      |
| `properties.payment_provider_id`             | `string`                                        |
| `properties.payment_provider_transaction_id` | `string` or `null`                              |

### invoice.payment\_processing

Issued when a payment for an invoice starts processing.

| key                              | schema                                          |
| -------------------------------- | ----------------------------------------------- |
| `invoice`                        | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.payment_provider`    | `"stripe"`                                      |
| `properties.payment_provider_id` | `string`                                        |

### invoice.payment\_succeeded

Issued when automated payment collection for an invoice succeeds for a configured payment gateway. This webhook is not sent for \$0 invoices that are automatically marked as paid upon issuance.

| key                                          | schema                                          |
| -------------------------------------------- | ----------------------------------------------- |
| `invoice`                                    | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.payment_provider`                | `"stripe"`                                      |
| `properties.payment_provider_id`             | `string`                                        |
| `properties.payment_provider_transaction_id` | `string`                                        |

### invoice.sync\_failed

Issued when an invoice fails to sync to the invoice provider.

| key                              | schema                                          |
| -------------------------------- | ----------------------------------------------- |
| `invoice`                        | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.payment_provider`    | `string`                                        |
| `properties.payment_provider_id` | `string`                                        |

### invoice.sync\_succeeded

Issued when an invoice successfully syncs to the invoice provider.

| key                              | schema                                          |
| -------------------------------- | ----------------------------------------------- |
| `invoice`                        | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties.payment_provider`    | `string`                                        |
| `properties.payment_provider_id` | `string`                                        |

### invoice.undo\_mark\_as\_paid

Issued when undoing the `Paid` status for an invoice that was manually marked as paid.

| key          | schema                                          |
| ------------ | ----------------------------------------------- |
| `invoice`    | [Invoice](/api-reference/invoice/fetch-invoice) |
| `properties` | `{}`                                            |

### plan.default\_version\_set

Issued when a plan's default version is set.

| key                                          | schema                                                                                                                                   |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `plan`                                       | Object with `id` (`string`), `external_plan_id` (`string` or `null`), and `name` (`string`). See [Plan](/api-reference/plan/fetch-plan). |
| `properties.previous_default_version_number` | `number`                                                                                                                                 |
| `properties.new_default_version_number`      | `number`                                                                                                                                 |

### plan.version\_created

Issued when a new plan version is created.

| key                                   | schema                                                                                                                                   |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `plan`                                | Object with `id` (`string`), `external_plan_id` (`string` or `null`), and `name` (`string`). See [Plan](/api-reference/plan/fetch-plan). |
| `properties.plan_version_number`      | `number`                                                                                                                                 |
| `properties.plan_version_description` | `string`                                                                                                                                 |

### price.edited

Issued when a price is edited. This webhook is only issued when metadata for the resource changes, as prices are otherwise immutable. The `previous_attributes` object will be present and populated with the previous state of any price attributes that have changed.

| key                                       | schema                                    |
| ----------------------------------------- | ----------------------------------------- |
| `price`                                   | [Price](/api-reference/price/fetch-price) |
| `properties.previous_attributes.metadata` | `object`                                  |

### resource\_event.test

Issued via the Orb UI to test if your webhook configuration is set up properly and ready to receive events from us.

| key       | schema   |
| --------- | -------- |
| `message` | `string` |

### subscription.cancellation\_scheduled

Issued when a subscription cancellation is scheduled for the future.

| key                            | schema                                                         |
| ------------------------------ | -------------------------------------------------------------- |
| `subscription`                 | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.cancellation_date` | `date-time`                                                    |

### subscription.cancellation\_unscheduled

Issued when a previously scheduled subscription cancellation is unscheduled/cancelled.

| key                                     | schema                                                         |
| --------------------------------------- | -------------------------------------------------------------- |
| `subscription`                          | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.original_cancellation_date` | `date-time`                                                    |

<Note>
  Unscheduling a cancellation is a lossy operation—the subscription may not fully match its original pre-cancellation state.
</Note>

### subscription.created

Issued when a subscription resource is created.

| key            | schema                                                         |
| -------------- | -------------------------------------------------------------- |
| `subscription` | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties`   | `{}`                                                           |

### subscription.edited

Issued when a subscription has been edited. This will not be triggered for changes to pricing.

| key                                                   | schema                                                         |
| ----------------------------------------------------- | -------------------------------------------------------------- |
| `subscription`                                        | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.previous_attributes.metadata`             | `object`                                                       |
| `properties.previous_attributes.default_invoice_memo` | `string`                                                       |
| `properties.previous_attributes.auto_collection`      | `boolean`                                                      |
| `properties.previous_attributes.net_terms`            | `number`                                                       |
| `properties.previous_attributes.invoicing_threshold`  | `number`                                                       |

### subscription.ended

Occurs whenever a customer’s subscription ends/lapses.

| key            | schema                                                         |
| -------------- | -------------------------------------------------------------- |
| `subscription` | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties`   | `{}`                                                           |

### subscription.fixed\_fee\_quantity\_updated

Issued when a subscription's fixed fee quantity has been updated.

| key                         | schema                                                         |
| --------------------------- | -------------------------------------------------------------- |
| `subscription`              | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.old_quantity`   | `number`                                                       |
| `properties.new_quantity`   | `number`                                                       |
| `properties.effective_date` | `date-time`                                                    |
| `properties.price_id`       | `string`                                                       |

### subscription.plan\_change\_scheduled

| key                           | schema                                                         |
| :---------------------------- | :------------------------------------------------------------- |
| `subscription`                | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.previous_plan_id` | `string`                                                       |
| `properties.new_plan_id`      | `string`                                                       |
| `properties.change_date`      | `string`                                                       |

### subscription.plan\_changed

Issued when a scheduled plan change occurs.

| key                           | schema                                                         |
| ----------------------------- | -------------------------------------------------------------- |
| `subscription`                | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.previous_plan_id` | `string`                                                       |

### subscription.plan\_version\_change\_scheduled

Issued when a plan version change is scheduled in the future for a subscription.

| key                                       | schema                                                         |
| ----------------------------------------- | -------------------------------------------------------------- |
| `subscription`                            | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.effective_date`               | `date-time`                                                    |
| `properties.previous_plan_version_number` | `number`                                                       |
| `properties.new_plan_version_number`      | `number`                                                       |

### subscription.plan\_version\_changed

Issued when a subscription moves to a new plan version.

| key                                       | schema                                                         |
| ----------------------------------------- | -------------------------------------------------------------- |
| `subscription`                            | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties.effective_date`               | `date-time`                                                    |
| `properties.previous_plan_version_number` | `number`                                                       |
| `properties.new_plan_version_number`      | `number`                                                       |

### subscription.started

Issued when a subscription begins.

| key            | schema                                                         |
| -------------- | -------------------------------------------------------------- |
| `subscription` | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties`   | `{}`                                                           |

### subscription.trial\_ended

Issued when a subscription's trial ends.

| key            | schema                                                         |
| :------------- | :------------------------------------------------------------- |
| `subscription` | [Subscription](/api-reference/subscription/fetch-subscription) |
| `properties`   | `{}`                                                           |

## Webhook Event Types: Usage Patterns and Balance Events

Orb currently issues the following usage patterns and balance events webhooks:

### customer.credit\_balance\_depleted

Issued when a customer's prepaid credit balance is depleted.

| key                                    | schema                                             |
| -------------------------------------- | -------------------------------------------------- |
| `customer`                             | [Customer](/api-reference/customer/fetch-customer) |
| `alert_configuration`                  | [Alert](/api-reference/alert/fetch-alert)          |
| `properties.pricing_unit.name`         | `string`                                           |
| `properties.pricing_unit.symbol`       | `string`                                           |
| `properties.pricing_unit.display_name` | `string`                                           |

### customer.credit\_balance\_dropped

Issued when a customer's prepaid credit balance is depleted to a configured threshold.

| key                                    | schema                                             |
| -------------------------------------- | -------------------------------------------------- |
| `customer`                             | [Customer](/api-reference/customer/fetch-customer) |
| `alert_configuration`                  | [Alert](/api-reference/alert/fetch-alert)          |
| `properties.balance_threshold`         | `string`                                           |
| `properties.pricing_unit.name`         | `string`                                           |
| `properties.pricing_unit.symbol`       | `string`                                           |
| `properties.pricing_unit.display_name` | `string`                                           |

### customer.credit\_balance\_recovered

Issued when a customer's prepaid credit balance is replenished after depletion.

| key                                    | schema                                             |
| -------------------------------------- | -------------------------------------------------- |
| `customer`                             | [Customer](/api-reference/customer/fetch-customer) |
| `alert_configuration`                  | [Alert](/api-reference/alert/fetch-alert)          |
| `properties.pricing_unit.name`         | `string`                                           |
| `properties.pricing_unit.symbol`       | `string`                                           |
| `properties.pricing_unit.display_name` | `string`                                           |

### subscription.alert\_disabled

Issued when Orb automatically disables an alert. Currently sent when a [grouped cost alert](/usage-alerting/grouped-cost-alerts) exceeds the per-evaluation group cardinality limit and is disabled for the affected subscription. `reason` identifies why the alert was disabled, and `cardinality` / `cardinality_limit` report the observed and maximum group counts.

| key                            | schema                                                         |
| ------------------------------ | -------------------------------------------------------------- |
| `subscription`                 | [Subscription](/api-reference/subscription/fetch-subscription) |
| `alert_configuration`          | [Alert](/api-reference/alert/fetch-alert)                      |
| `properties.reason`            | `string`                                                       |
| `properties.cardinality`       | `number`                                                       |
| `properties.cardinality_limit` | `number`                                                       |

### subscription.cost\_exceeded

Issued when a subscription's accrued spend for a month exceeds a pre-configured currency amount.

<Note>
  Orb will not evaluate alerts on cost that are configured with a threshold below the total of a plan's fixed costs with a prioritized cadence during billing period rollovers. These alerts can be expected to fire near the first actual usage event received for the new billing period and will subsequently be evaluated several times a day. The evaluated spend is the running invoice total after any credit offsets, so prepurchased credits applied to the subscription reduce the spend that is compared against the threshold.
</Note>

| key                           | schema                                                         |
| ----------------------------- | -------------------------------------------------------------- |
| `subscription`                | [Subscription](/api-reference/subscription/fetch-subscription) |
| `alert_configuration`         | [Alert](/api-reference/alert/fetch-alert)                      |
| `properties.timeframe_start`  | `date-time`                                                    |
| `properties.timeframe_end`    | `date-time`                                                    |
| `properties.amount_threshold` | `number`                                                       |

### subscription.grouped\_cost\_exceeded

Issued when one or more groups of a [grouped cost alert](/usage-alerting/grouped-cost-alerts) exceed a pre-configured currency amount. A single event batches every group that crossed a threshold in the same evaluation. Each entry in `groups` reports that group's `group_values` (in `grouping_keys` order), the `amount_threshold` it crossed, and its `evaluated_amount`.

| key                                    | schema                                                         |
| -------------------------------------- | -------------------------------------------------------------- |
| `subscription`                         | [Subscription](/api-reference/subscription/fetch-subscription) |
| `alert_configuration`                  | [Alert](/api-reference/alert/fetch-alert)                      |
| `properties.timeframe_start`           | `date-time`                                                    |
| `properties.timeframe_end`             | `date-time`                                                    |
| `properties.grouping_keys`             | `array` of `string`                                            |
| `properties.groups`                    | `array` of objects                                             |
| `properties.groups[].group_values`     | `array` of `string`                                            |
| `properties.groups[].amount_threshold` | `number`                                                       |
| `properties.groups[].evaluated_amount` | `number`                                                       |

### subscription.usage\_exceeded

Issued when a billable metric in a subscription exceeds a pre-configured quantity threshold.

| key                             | schema                                                         |
| ------------------------------- | -------------------------------------------------------------- |
| `subscription`                  | [Subscription](/api-reference/subscription/fetch-subscription) |
| `alert_configuration`           | [Alert](/api-reference/alert/fetch-alert)                      |
| `properties.billable_metric_id` | `string`                                                       |
| `properties.timeframe_start`    | `date-time`                                                    |
| `properties.timeframe_end`      | `date-time`                                                    |
| `properties.quantity_threshold` | `number`                                                       |

## Webhook Event Types: Accounting Sync

Orb issues the following webhooks when syncing resources to external accounting systems.

<Note>
  These events are only emitted when the Accounting Sync integration is enabled and configured. Supported connection types are "quickbooks" and "netsuite". See <a href="/integrations-and-exports/accounting">Accounting</a>

  and <a href="/integrations-and-exports/quickbooks">QuickBooks</a>

  setup guides.
</Note>

### Accounting Sync Record object

The `accounting_sync_record` included in these events contains the following fields:

| key                    | schema   |
| ---------------------- | -------- |
| `id`                   | `string` |
| `record_type`          | `string` |
| `sync_action`          | `string` |
| `status`               | `string` |
| `customer_id`          | `string` |
| `provider_customer_id` | `string` |
| `error_details`        | `object` |

### credit\_block.accounting\_sync\_failed

Issued when a credit block fails to sync to the configured accounting system.

| key                          | schema                                                   |
| ---------------------------- | -------------------------------------------------------- |
| `block`                      | [Credit block](/api-reference/credit/fetch-credit-block) |
| `accounting_sync_record`     | `object`                                                 |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")                    |
| `properties.failure_reason`  | `string`                                                 |

### credit\_block.accounting\_sync\_succeeded

Issued when a credit block successfully syncs to the configured accounting system.

| key                          | schema                                                   |
| ---------------------------- | -------------------------------------------------------- |
| `block`                      | [Credit block](/api-reference/credit/fetch-credit-block) |
| `accounting_sync_record`     | `object`                                                 |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")                    |

### credit\_note.accounting\_sync\_failed

Issued when a credit note fails to sync to the configured accounting system.

| key                          | schema                                                      |
| ---------------------------- | ----------------------------------------------------------- |
| `credit_note`                | [Credit note](/api-reference/credit-note/fetch-credit-note) |
| `accounting_sync_record`     | `object`                                                    |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")                       |
| `properties.failure_reason`  | `string`                                                    |

### credit\_note.accounting\_sync\_succeeded

Issued when a credit note successfully syncs to the configured accounting system.

| key                          | schema                                                      |
| ---------------------------- | ----------------------------------------------------------- |
| `credit_note`                | [Credit note](/api-reference/credit-note/fetch-credit-note) |
| `accounting_sync_record`     | `object`                                                    |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")                       |

### customer.accounting\_sync\_failed

Issued when a customer fails to sync to the configured accounting system.

| key                          | schema                                             |
| ---------------------------- | -------------------------------------------------- |
| `customer`                   | [Customer](/api-reference/customer/fetch-customer) |
| `accounting_sync_record`     | `object`                                           |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")              |
| `properties.failure_reason`  | `string`                                           |

### customer.accounting\_sync\_succeeded

Issued when a customer successfully syncs to the configured accounting system.

| key                          | schema                                             |
| ---------------------------- | -------------------------------------------------- |
| `customer`                   | [Customer](/api-reference/customer/fetch-customer) |
| `accounting_sync_record`     | `object`                                           |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")              |

### invoice.accounting\_sync\_failed

Issued when an invoice fails to sync to the configured accounting system.

| key                          | schema                                          |
| ---------------------------- | ----------------------------------------------- |
| `invoice`                    | [Invoice](/api-reference/invoice/fetch-invoice) |
| `accounting_sync_record`     | `object`                                        |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")           |
| `properties.failure_reason`  | `string`                                        |

### invoice.accounting\_sync\_succeeded

Issued when an invoice successfully syncs to the configured accounting system.

| key                          | schema                                          |
| ---------------------------- | ----------------------------------------------- |
| `invoice`                    | [Invoice](/api-reference/invoice/fetch-invoice) |
| `accounting_sync_record`     | `object`                                        |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")           |

### subscription.accounting\_sync\_failed

Issued when a subscription fails to sync to the configured accounting system.

| key                          | schema                                                         |
| ---------------------------- | -------------------------------------------------------------- |
| `subscription`               | [Subscription](/api-reference/subscription/fetch-subscription) |
| `accounting_sync_record`     | `object`                                                       |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")                          |
| `properties.failure_reason`  | `string`                                                       |

### subscription.accounting\_sync\_succeeded

Issued when a subscription successfully syncs to the configured accounting system.

| key                          | schema                                                         |
| ---------------------------- | -------------------------------------------------------------- |
| `subscription`               | [Subscription](/api-reference/subscription/fetch-subscription) |
| `accounting_sync_record`     | `object`                                                       |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite")                          |

### transaction.accounting\_sync\_failed

Issued when a transaction fails to sync to the configured accounting system.

| key                          | schema                                |
| ---------------------------- | ------------------------------------- |
| `transaction`                | `object`                              |
| `accounting_sync_record`     | `object`                              |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite") |
| `properties.failure_reason`  | `string`                              |

### transaction.accounting\_sync\_succeeded

Issued when a transaction successfully syncs to the configured accounting system.

| key                          | schema                                |
| ---------------------------- | ------------------------------------- |
| `transaction`                | `object`                              |
| `accounting_sync_record`     | `object`                              |
| `properties.connection_type` | `string` ("quickbooks" or "netsuite") |

## Webhook Event Types: Data Exports

Orb currently issues the following webhooks for data exports:

### data\_exports.transfer\_error

Issued upon a failed transfer of resource data to a destination.

| key                                | schema              |
| ---------------------------------- | ------------------- |
| `properties.destination_name`      | `string`            |
| `properties.description`           | `string`            |
| `properties.resources`             | `array` of `string` |
| `properties.rows_transferred`      | `number`            |
| `properties.transfer_started_at`   | `date-time`         |
| `properties.transfer_ended_at`     | `date-time`         |
| `properties.transfer_blamed_party` | `string`            |

### data\_exports.transfer\_success

Issued upon a successful transfer of resource data to a destination.

| key                              | schema              |
| -------------------------------- | ------------------- |
| `properties.destination_name`    | `string`            |
| `properties.description`         | `string`            |
| `properties.resources`           | `array` of `string` |
| `properties.rows_transferred`    | `number`            |
| `properties.transfer_started_at` | `date-time`         |
| `properties.transfer_ended_at`   | `date-time`         |

## Webhooks security

Each webhook event sent by Orb also includes two specific headers in the request:

1. `X-Orb-Timestamp`: This header represents the time that the webhook was sent from Orb. You can check this timestamp and compare it to a configured threshold in your system, in order to prevent processing of the webhook event. This can be a mitigation against [replay attacks](https://en.wikipedia.org/wiki/Replay_attack) where webhook events are re-sent, causing downstream systems to behave unexpectedly.
2. `X-Orb-Signature`: The signature header (formatted as `v1=<signature>`) is a security header which can be used to confirm that the webhook event originated from Orb. We highly recommend verifying the signature, and only processing events where the header matches the signature you generate. Since each webhook endpoint is associated with a secret, your backend server should re-compute the signature by preparing the payload and subsequently computing an HMAC with the SHA 256 function.
   * The `payload` for the HMAC is the literal `"v1:"` followed by the ISO format `X-Orb-Timestamp` and finally the literal `:` followed by the event message body itself.
   * You should use the configured secret for the endpoint URL as the signing secret for the HMAC.
   * When comparing to your generated HMAC, you can either prefix the literal `v1=` to compare with `X-Orb-Signature` header directly, or extract the element after `v1=` in `X-Orb-Signature` to check against your generated value.

### Webhooks verification

Orb's SDKs provide verification methods for your webhook events, available in [Python](https://github.com/orbcorp/orb-python/blob/d5f974a033edd347555105d42b84200c12a723f3/src/orb/resources/webhooks.py#L21), [Node](https://github.com/orbcorp/orb-node/blob/bac8b816fd3aad7abc6a63ce22ea93eeba61521b/src/resources/webhooks.ts#L7), and [Go](https://github.com/orbcorp/orb-go/blob/7b7d9ac15b286914c72eef35cfbfd2c46301bf2e/webhook.go#L21).

Here's an example verification snippet implemented as a Flask endpoint:

```python theme={null}
from flask import Flask, request
import hmac
from hashlib import sha256

app = Flask(__name__)

## Example using Flask
@app.route('/webhook-handler', methods=['POST'])
def handle_webhook():
    # parse webhook JSON
    webhook_event = request.json

    if webhook_event is None: 
        # could not parse request
        return ('Unable to parse notification.', 400)

    expected_signature = request.headers["X-Orb-Signature"]
    iso_format_delivery_time = request.headers["X-Orb-Timestamp"]

    secret_string = "<insert your secret string here>"  
    secret = bytes(secret_string, "utf-8")

    # Prefix the beginning of the signature with `v1:<isoformat timestamp>`
    prefix = "v1:{0}:".format(iso_format_delivery_time)

    # Convert to bytes and append the body of the request
    message = prefix.encode("utf-8") + request.data

    # Generate an encode message based on the secret and the message string with sha256.
    hmac_object = hmac.new(secret, message, sha256)
    created_signature = "v1=" + hmac_object.hexdigest()
    
    if not expected_signature == created_signature:
        return ('Unable to verify webhook signature.', 400)
    
    # Handle based on webhook_event.type
    return ('Successfully processed webhook!', 200)
```
