Webhooks

Webhook Setup

You will receive notifications via a webhook whenever there are new events associated with a Connection or change in data.

Rutter offers webhooks for all platforms, including platforms that do not natively offer webhooks. Each time an Incremental Sync runs, our system automatically computes any data changes and fires webhooks accordingly.

Additionally, Rutter offers real-time webhooks for QuickBooks Online, Xero, Stripe, and Sage Intacct. This feature takes advantage of the native webhook capabilities in these platforms to send webhooks as soon as data changes in the platform, rather than waiting for the next Incremental Sync. Please see the Real-Time Webhooks section below for details.

Set up tunneling

We recommend using ngrok to serve your backend over a public URL.

After installing ngrok, if your backend is running on port 4000, run ngrok http 4000. This will then give you public URLs that Rutter can hit to send updates.

Configure your webhook

To let Rutter know what your webhook URL is, go to the Platforms page in the dashboard. Paste in the public URL that ngrok generated for you in the previous step.

Handle webhooks

That's it! Now, you can run through the connection flow again, and check that events are sent to your webhook URL.

Webhook Security

Webhook signatures provide additional security to webhooks emitted by Rutter by verifying that the webhook wasn't sent from an unknown or malicious entity. To do this, Rutter signs each webhook payload with a secret. The resulting signature is included in the header of the request, which you can then use to verify that the webhook received is from Rutter, guaranteeing the validity of the webhook.

Signature Headers

Every webhook sent by Rutter contains two signature headers:

X-Rutter-Signature — The primary signature. Its value is the prefix sha256= followed by a base64-encoded HMAC-SHA256 hash of the webhook payload, where the secret used to generate the hash is your organization's client secret.

X-Rutter-Signatures — A comma-separated list of all currently active signatures. During normal operation this list contains a single entry equal to X-Rutter-Signature. During a client secret rotation grace period it contains two entries — the new secret's signature first, followed by the expiring secret's signature — so that you can accept webhooks with either secret while completing your rotation.

Verifying Signatures

To verify a webhook, iterate the values in X-Rutter-Signatures and accept the webhook if any one of them matches the HMAC-SHA256 signature you compute from your stored client secret(s). This ensures your endpoint remains operational throughout a secret rotation.

  1. Split the X-Rutter-Signatures header value on ", " to get the list of signatures.
  2. For each of your active client secrets, compute sha256= + base64(HMAC-SHA256(payload, secret)).
  3. Accept the webhook if any computed signature matches any entry in the list.

Note

During a rotation grace period both your old and new client secrets are active. Store both until the grace period ends and all in-flight webhooks have been processed.

Webhook Acknowledgement

When Rutter sends a webhook to your endpoint, your server must respond with a 2xx HTTP status code within 5 seconds. Any non-2xx response or a timeout will be treated as a failed delivery attempt, and Rutter will retry the webhook.

Webhook Retries

If we receive a failure HTTP status code (or no response within 5 seconds) from your server when sending a webhook, we will retry delivery using an exponential backoff strategy with jitter. Retries continue for up to 15 minutes from the webhook's creation time. After that window, the webhook is marked as permanently failed and no further retries are attempted.

The approximate retry schedule is as follows:

AttemptDelayTotal elapsed
Initial delivery0s
1st retry~15s~15s
2nd retry~25s~40s
3rd retry~45s~1.5 min
4th retry~1.5 min~3 min
5th retry~3 min~6 min
6th retry~5.5 min~11 min

Note

Each retry delay includes a small amount of random jitter (up to 10 seconds) to prevent thundering herd issues. The exact timing of each retry may vary slightly. All retry delays are capped at 15 minutes.

Special Considerations

When working with webhooks, please keep the following in mind:

Webhooks that have the same payload may be sent multiple times. This can be caused by a variety of reasons, such as when the underlying raw platform data changes but not the standardized Rutter data object. Please make sure your webhook handler accounts for this behavior.

Webhooks are not 100% reliable. Expect a small percentage of webhooks to get dropped under normal working conditions. Make sure to handle these missing webhooks gracefully, so that the application still syncs even if no webhooks are received. We recommend calling the API endpoints regularly to check for updates in addition to using webhooks for real-time updates.

Webhooks will still be fired even if the entity creation is done via Rutter's API. For example, sending a request to POST /expenses will result in an EXPENSE_CREATED webhook for that entity.

Identifying Changes You Made Yourself

Entity webhooks (*_CREATED, *_UPDATED, *_DELETED) include a job_id field when — and only when — the change originated from one of your own Rutter API writes. Its value is the id of the asynchronous job that performed the write, and matches the job.id of the corresponding JOB_COMPLETED webhook.

1
{
2
"type": "VENDOR",
3
"code": "VENDOR_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"job_id": "3446b185-117f-46bc-939b-aa53de5c35c1",
7
"vendor": {
8
// ... Created Vendor object
9
}
10
}

If the field is absent, the change was picked up from the platform — an end user created or edited the record in the accounting system directly.

This is useful if you write to a platform and also listen to entity webhooks to sync changes back, since it lets you tell your own writes apart from genuine end-user activity instead of processing them twice. Because job_id is also the correlation key for JOB_COMPLETED, the two webhooks can be handled in either order — the entity webhook and the job webhook for the same write carry the same id, and Rutter does not guarantee which arrives first.

Note

Treat a present job_id as authoritative: that change came from your API call. Treat an absent job_id as "not attributable to one of your writes", which is not quite the same as "an end user did this". Three cases produce no job_id even though a write was involved:

  • Only the record you named is attributed. job_id is set for the entity your request targeted. Records touched incidentally by the same call — a vendor created as a side effect of creating a bill, records updated by a post-write hook, or related records re-synced after the write — arrive without a job_id.
  • A follow-up sync of the record you just wrote. After a write, Rutter re-reads the record from the platform. If the platform returns it in a slightly different shape than the write response, that produces an additional *_UPDATED webhook, with no job_id, usually within a minute. On QuickBooks Online this happens routinely rather than rarely.
  • QuickBooks Desktop is not covered, as its writes do not run through the pipeline that sets this field.

So job_id is well suited to suppressing duplicate handling of your own *_CREATED events. Do not use the absence of job_id on an *_UPDATED event to conclude a human edited the record. Handlers should be idempotent regardless — webhook delivery is at-least-once.


Connections Webhooks

You will receive notifications via a webhook whenever there are new events associated with a Connection. All webhooks related to a connection have a type of CONNECTION.

INITIAL_UPDATE

This webhook fires after an initial data download for a Connection has been completed. You can now send requests to Rutter to fetch merchant data.

1
{
2
"type": "CONNECTION",
3
"code": "INITIAL_UPDATE",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65"
6
}

Attempting to fetch data from a Connection without receiving the INITIAL_UPDATE webhook will return a PRODUCT_NOT_READY error.

If your organization has data batching enabled, this webhook will fire after a batch of historical data for a Connection has been synchronized. You can continue to fetch data while this process occurs.

Note

HISTORICAL_UPDATE will only fire if you have data batching enabled.

1
{
2
"type": "CONNECTION",
3
"code": "HISTORICAL_UPDATE",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
// Array containing information about which objects have been synchronized
7
"entities_included_to_time_range": [
8
{
9
"platformEntity":"ORDERS",
10
"xMonthsAgo":1
11
},
12
{
13
"platformEntity":"CREDIT_MEMOS",
14
"xMonthsAgo":1
15
}
16
],
17
}

INCREMENTAL_SYNC_COMPLETED

This webhook fires after a manual incremental sync has been completed for a Connection. Manual incremental syncs are triggered through the Rutter dashboard and check for new or updated data since the last sync.

Note

Currently, INCREMENTAL_SYNC_COMPLETED only fires for manual incremental syncs triggered via the dashboard. Scheduled and webhook-triggered incremental syncs do not fire this webhook to reduce overall webhook volume.

1
{
2
"type": "CONNECTION",
3
"code": "INCREMENTAL_SYNC_COMPLETED",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"incremental_sync_type": "manual",
7
"entities": ["ORDER"]
8
}

entities lists the Rutter entities explicitly requested via object_types on POST /connections/incremental_sync. It's null when object_types was omitted (a full sync of all entities), and [] when object_types was explicitly passed as an empty array (no entities synced).

CONNECTION_UPDATED

This webhook fires after an end user re-authenticates an existing Connection. The access_token value stays the same even if the Connection is updated.

1
{
2
"type": "CONNECTION",
3
"code": "CONNECTION_UPDATED",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"store_unique_id": "AWMFIE33LD"
7
}

CONNECTION_NEEDS_UPDATE

This webhook fires after a merchant unauthorizes/uninstalls an existing Connection, or if the authentication fails for any other reason. The webhook payload includes a URL that you can share directly with the merchant to re-authenticate them. This webhook is supported for all platforms except Intuit Bank Feeds.

1
{
2
"type": "CONNECTION",
3
"code": "CONNECTION_NEEDS_UPDATE",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"update_url": "https://link.rutterapi.com/connection/3adc1519-0d6e-4222-83de-25b457cf42be"
7
}

CONNECTION_DISABLED

This webhook fires after Rutter has encountered a problem with a connection and has temporarily disabled access to it. For example, the merchant's store got suspended by the platform, it would cause the connection to be disabled. Usually, there are additional steps this merchant needs to do in beyond simply reauthenticating depending on circumstances. To understand why it's disabled, you can use Fetch a Connection Status to find out and take actions accordingly with merchants.

1
{
2
"type": "CONNECTION",
3
"code": "CONNECTION_DISABLED",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"disable_error": "Reached same error over 100 times",
7
"disable_message": "Error: HTTP server returned 500"
8
}

This webhook fires after an error occurs during the authentication process. The webhook payload includes some human-readable details around the error, and a URL that you can share directly with the merchant to re-authenticate them.

1
{
2
"type": "CONNECTION",
3
"code": "CONNECTION_LINK_ERROR",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"update_url": "https://link.rutterapi.com/connection/3adc1519-0d6e-4222-83de-25b457cf42be",
7
"message": "The merchant denied access during OAuth",
8
"platform": "SHOPIFY"
9
}

CONNECTION_ERROR

This webhook after an error occurs for a connection. Errors can be related to data synchronization or issues connecting to a merchant's store after authentication is complete. The error message will contain information about the connection issue.

1
{
2
"type": "CONNECTION",
3
"code": "CONNECTION_ERROR",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"message": "Cloudflare is enabled on this store and Rutter requests are blocked.",
7
}

CONNECTION_AUTHENTICATED

This webhook fires for an INTUIT_BANK_FEEDS connection when authentication is successfully completed between Rutter and Intuit.

1
{
2
"type": "CONNECTION",
3
"code": "CONNECTION_AUTHENTICATED",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"platform": "INTUIT_BANK_FEEDS"
7
}

Accounting Webhooks

Account Webhooks

To see the Rutter account schema, please see Account.

ACCOUNT_CREATED

1
{
2
"type": "ACCOUNT",
3
"code": "ACCOUNT_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"account": {
7
// ... Created Account object
8
}
9
}

ACCOUNT_UPDATED

1
{
2
"type": "ACCOUNT",
3
"code": "ACCOUNT_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"account": {
7
// ... Updated Account object
8
}
9
}

Bills Webhooks

To see the Rutter Bill schema, please see Bill.

BILL_CREATED

1
{
2
"type": "BILL",
3
"code": "BILL_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"bill": {
7
// ... Created Bill object
8
}
9
}

BILL_UPDATED

1
{
2
"type": "BILL",
3
"code": "BILL_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"bill": {
7
// ... Updated Bill object
8
}
9
}

Bill Payments Webhooks

To see the Rutter Bill Payment schema, please see Bill Payments.

BILL_PAYMENT_CREATED

1
{
2
"type": "BILL_PAYMENT",
3
"code": "BILL_PAYMENT_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"bill_payment": {
7
// ... Created Bill payment object
8
}
9
}

BILL_UPDATED

1
{
2
"type": "BILL_PAYMENT",
3
"code": "BILL_PAYMENT_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"bill_payment": {
7
// ... Updated Bill payment object
8
}
9
}

Customers Webhooks

To see the Rutter Customer schema, please see Customer.

CUSTOMER_CREATED

1
{
2
"type": "CUSTOMER",
3
"code": "CUSTOMER_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"customer": {
7
// ... Created accounting customer object
8
}
9
}

CUSTOMER_UPDATED

1
{
2
"type": "CUSTOMER",
3
"code": "CUSTOMER_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"customer": {
7
// ... Updated accounting customer object
8
}
9
}

Invoices Webhooks

To see the Rutter Invoice schema, please see Invoices.

INVOICE_CREATED

1
{
2
"type": "INVOICE",
3
"code": "INVOICE_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"invoice": {
7
// ... Created invoice object
8
}
9
}

INVOICE_UPDATED

1
{
2
"type": "INVOICE",
3
"code": "INVOICE_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"invoice": {
7
// ... Updated invoice object
8
}
9
}

Invoice Credit Memos Webhooks

To see the Rutter Invoice Credit Memo schema, please see Invoices Credit Memos.

INVOICE_CREDIT_MEMO_CREATED

1
{
2
"type": "INVOICE_CREDIT_MEMO",
3
"code": "INVOICE_CREDIT_MEMO_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"invoice_credit_memo": {
7
// ... Created Invoice Credit Memo object
8
}
9
}

INVOICE_CREDIT_MEMO_UPDATED

1
{
2
"type": "INVOICE_CREDIT_MEMO",
3
"code": "INVOICE_CREDIT_MEMO_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"invoice_credit_memo": {
7
// ... Updated Invoice Credit Memo object
8
}
9
}

Journal Entries Webhooks

To see the Rutter Journal Entry schema, please see Journal Entries.

JOURNAL_ENTRY_CREATED

1
{
2
"type": "JOURNAL_ENTRY",
3
"code": "JOURNAL_ENTRY_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"journal_entry": {
7
// ... Created Journal Entry object
8
}
9
}

JOURNAL_ENTRY_UPDATED

1
{
2
"type": "JOURNAL_ENTRY",
3
"code": "JOURNAL_ENTRY_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"journal_entry": {
7
// ... Updated Journal Entry object
8
}
9
}

Vendors Webhooks

To see the Rutter Vendor schema, please see Vendors.

VENDOR_CREATED

1
{
2
"type": "VENDOR",
3
"code": "VENDOR_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"vendor": {
7
// ... Created vendor object
8
}
9
}

VENDOR_UPDATED

1
{
2
"type": "VENDOR",
3
"code": "VENDOR_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"vendor": {
7
// ... Updated vendor object
8
}
9
}

Commerce Webhooks

Orders Webhooks

You will receive notifications via a webhook whenever there are new events associated with an order. All webhooks related to an order have a type of ORDER.

ORDER_CREATED

Fired after a new order has been created for a connection.

1
{
2
"type": "ORDER",
3
"code": "ORDER_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"order": {
7
// ... New order object
8
}
9
}

ORDER_UPDATED

Fired after an order has been updated for a connection. If any field within Orders changed, including content of line_items, status, payment_status, etc, we will fire this webhook.

1
{
2
"type": "ORDER",
3
"code": "ORDER_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"order": {
7
// ... Updated order object
8
}
9
}

ORDER_DELETED

Fired after an order has been deleted.

1
{
2
"type": "ORDER",
3
"code": "ORDER_DELETED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"order": {
7
"id": "60fde312-0a7e-4bda-b838-3aa19a5c57e4"
8
}
9
}

Products Webhooks

You will receive notifications via a webhook whenever there are new events associated with a product. All webhooks related to a product have a type of PRODUCT and a code with the specific type of event which occurred.

PRODUCT_UPDATED

Fired after a product has been updated.

1
{
2
"type": "PRODUCT",
3
"code": "PRODUCT_UPDATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"product": {
7
// ... Updated product object
8
}
9
}

PRODUCT_CREATED

Fired after a product has been created.

1
{
2
"type": "PRODUCT",
3
"code": "PRODUCT_CREATED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"product": {
7
// ... New product object
8
}
9
}

PRODUCT_DELETED

Fired after a product has been deleted. This is available only to Shopify, WooCommerce, and Wix. Please see here for more explanation.

1
{
2
"type": "PRODUCT",
3
"code": "PRODUCT_DELETED",
4
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
5
"connection_id": "222c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"product": {
7
"id": "60fde312-0a7e-4bda-b838-3aa19a5c57e4"
8
}
9
}

PRODUCT_READY

In platforms where POST /product is a long running job (specifically Amazon), a job ID will be returned as a response. A PRODUCT_READY webhook will be fired when the job has completed. A product object will be returned on POST /product success, and an error message will be returned on failure.

1
{
2
"type": "PRODUCT",
3
"code": "PRODUCT_READY",
4
"job_id": "fc7e5f82-b6f3-4ad7-94d9-f00f9c864fa9",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"product": {
7
"id": "60fde312-0a7e-4bda-b838-3aa19a5c57e4",
8
},
9
"error": null
10
}

PRODUCT_FINISH_FAILED

In the platforms where image upload and/or variant create run asynchronously after the initial POST /products request, we will send an error message in case variant create or image upload fails. In the case of success, we will send a PRODUCT_UPDATE webhook.

1
{
2
"type": "PRODUCT",
3
"code": "PRODUCT_FINISH_FAILED",
4
"job_id": "fc7e5f82-b6f3-4ad7-94d9-f00f9c864fa9",
5
"connection_id": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"productRequestBody": {
7
// Original product request body sent in POST /products
8
},
9
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
10
"existingProductId": "60fde312-0a7e-4bda-b838-3aa19a5c57e4",
11
"error_message": "Something went wrong. Contact support@rutterapi.com for information."
12
}

Store Webhooks

You will receive notifications via a webhook whenever there are new events associated with a Store. All webhooks related to a store have a type of STORE.

STORE_UPDATED

This webhook fires a merchant's store configuration changes (the most common changes are default currency change and default language change)

1
{
2
"type": "STORE",
3
"code": "STORE_UPDATED",
4
"connection_id": "3adc1519-0d6e-4222-83de-25b457cf42be",
5
"access_token": "313c3e00-2bbc-4b2e-a9dc-13abed546b65",
6
"store": {
7
"default_currency": "EUR",
8
"email": "example@rutterapi.com",
9
"id": "3e406708-e696-4454-9367-a6bb2bd9bdf0",
10
"store_name": "Rutter test store",
11
"url": "www.google.com"
12
}
13
}

Delete Webhooks

When Rutter detects that an entity is deleted directly from the underlying platform, you will receive a notification via webhook.

Please be aware that marking a resource as inactive is NOT the same as deleting it, and a webhook will not be sent in that case.

Delete webhooks are supported for select resources and platforms. See the table below for the currently enabled list:

Delete EventEntity NameSupported Platforms
ACCOUNT_DELETEDaccountZOHOBOOKS, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
ACCOUNTING_CUSTOMER_REFUND_DELETEDcustomer_refundXERO, QUICKBOOKS, NETSUITE
BANK_DEPOSIT_DELETEDbank_depositZOHOBOOKS, XERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
BANK_FEED_ACCOUNT_DELETEDbank_feed_accountXERO
BANK_TRANSFER_DELETEDbank_transferZOHOBOOKS, SAGE_INTACCT_V2, QUICKBOOKS, NETSUITE
BILL_DELETEDbillXERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
BILL_CREDIT_MEMO_DELETEDbill_credit_memoXERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
BILL_CREDIT_APPLICATION_DELETEDbill_credit_applicationSAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
BILL_PAYMENT_DELETEDbill_paymentZOHOBOOKS, XERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
CLASS_DELETEDclassSAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, NETSUITE
COMPANY_INFO_DELETEDcompany_infoNETSUITE
CURRENCY_DELETEDcurrencyQUICKBOOKS_DESKTOP, NETSUITE
CUSTOMER_DELETEDcustomerZOHOBOOKS, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
DEPARTMENT_DELETEDdepartmentSAGE_INTACCT_V2, NETSUITE
EXPENSE_DELETEDexpenseXERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
EXPENSE_REFUND_DELETEDexpense_refundQUICKBOOKS, NETSUITE
INVOICE_DELETEDinvoiceZOHOBOOKS, XERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
INVOICE_CREDIT_APPLICATION_DELETEDinvoice_credit_applicationSAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
INVOICE_CREDIT_MEMO_DELETEDinvoice_credit_memoXERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
INVOICE_PAYMENT_DELETEDinvoice_paymentZOHOBOOKS, XERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
ITEM_DELETEDitemZOHOBOOKS, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
JOURNAL_ENTRY_DELETEDjournal_entryZOHOBOOKS, XERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
LOCATION_DELETEDlocationSAGE_INTACCT_V2, NETSUITE
PAYMENT_METHOD_DELETEDpayment_methodQUICKBOOKS_DESKTOP, NETSUITE
PAYMENT_TERM_DELETEDpayment_termNETSUITE
PROJECT_DELETEDprojectZOHOBOOKS, SAGE_INTACCT_V2
PURCHASE_ORDER_DELETEDpurchase_orderXERO, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE
SALES_ORDER_DELETEDsales_orderXERO, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, NETSUITE
SALES_RECEIPT_DELETEDsales_receiptNETSUITE
SUBSIDIARY_DELETEDsubsidiarySAGE_INTACCT_V2, NETSUITE
TASK_DELETEDtaskSAGE_INTACCT_V2
TAX_RATE_DELETEDtax_rateZOHOBOOKS, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, NETSUITE
VENDOR_DELETEDvendorZOHOBOOKS, SAGE_INTACCT_V2, QUICKBOOKS_DESKTOP, QUICKBOOKS, NETSUITE

The structure of the request payload will be the same between all resources, with the exception of the resource key. For example, the below payload will be sent in the case of a BILL_DELETED event. Please note that the bill key will vary between resources, but will always be equal to the entity key found in the event table above.

1
{
2
"type": "BILL",
3
"code": "BILL_DELETED",
4
"connection_id": "f53bd178-0834-456d-adc0-735a6cf64002",
5
"access_token": "c37ffdf3-48b3-4e7b-a224-1732d71e655f",
6
"bill": {
7
"id": "3ca7e1cb-48ce-4bb9-a0d7-6ab6250aff76",
8
"deleted_at": "2024-01-03T13:47:26.000Z"
9
}
10
}

The list of webhook events above is not exhaustive. For a full list of webhook events, visit the webhook section of the Rutter dashboard.

Real-Time Webhooks

To configure real-time webhooks, head to the Platforms tab of the Rutter Dashboard. Then, select QuickBooks, Xero, Stripe, or Sage Intacct. Select the Webhooks tab, and follow the configuration instructions.

Rutter supports real-time webhooks when the following entities are created or updated.

Xero

  • Invoices
  • Customers ("Contacts" in Xero)
  • Vendors ("Contacts" in Xero)

These are the only entities that Xero's platform makes available for real-time updates. Additional entities are not available due to Xero's limitations.

QuickBooks

  • Accounts
  • Bank Deposits
  • Bills
  • Bill Payments
  • Bill Credit Memos
  • Classes
  • Company Info
  • Currencies
  • Customers
  • Departments
  • Expenses
  • Invoices
  • Invoice Payments
  • Invoice Credit Memos
  • Items
  • Journal Entries
  • Payment Methods
  • Payment Terms
  • Purchase Orders
  • Bank Transfers
  • Vendors

Note

Company Info real-time updates are driven by changes to the QuickBooks Preferences object. Edits made directly to the company's name or address in QuickBooks (rather than through preferences) will not trigger a real-time webhook; these changes will still be picked up on the next Incremental Sync.

Stripe

  • Payouts
  • Transactions

Sage Intacct

  • Accounts
  • Bank Accounts
  • Bank Deposits
  • Bills
  • Bill Payments
  • Classes
  • Customers
  • Departments
  • Invoices
  • Invoice Payments
  • Items
  • Journal Entries
  • Locations
  • Projects
  • Taxes
  • Vendors