You’ll need to configure an endpoint our servers can call whenever user data changes trigger notifications. Once webhooks are active, we’ll send the requested event data, changes, and notifications.
If you haven’t already, set up OAuth 2.0 for your app.
Even if webhooks are active, you’ll only receive change notifications for QuickBooks Online companies that are connected and authorized via OAuth 2.0.
Here ia an example webhook implementation for Java.
See which entities and operations support webhooks
This table shows the entities that support webhooks and the permitted operations.
| Create | Update | Delete | Merge | Void | Emailed | |
| Account | ✓ | ✓ | ✓ | ✓ | ||
| Bill | ✓ | ✓ | ✓ | |||
| BillPayment | ✓ | ✓ | ✓ | ✓ | ||
| Budget | ✓ | ✓ | ||||
| Class | ✓ | ✓ | ✓ | ✓ | ||
| CreditMemo | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Currency | ✓ | ✓ | ||||
| Customer | ✓ | ✓ | ✓ | ✓ | ||
| Department | ✓ | ✓ | ✓ | |||
| Deposit | ✓ | ✓ | ✓ | |||
| Employee | ✓ | ✓ | ✓ | ✓ | ||
| Estimate | ✓ | ✓ | ✓ | ✓ | ||
| Invoice | ✓ | ✓ | ✓ | ✓ | ✓ | |
| Item | ✓ | ✓ | ✓ | ✓ | ||
| JournalCode | ✓ | ✓ | ||||
| JournalEntry | ✓ | ✓ | ✓ | |||
| Payment | ✓ | ✓ | ✓ | ✓ | ✓ | |
| PaymentMethod | ✓ | ✓ | ✓ | |||
| Preferences | ✓ | |||||
| Purchase | ✓ | ✓ | ✓ | ✓ | ||
| PurchaseOrder | ✓ | ✓ | ✓ | ✓ | ||
| RefundReceipt | ✓ | ✓ | ✓ | ✓ | ✓ | |
| SalesReceipt | ✓ | ✓ | ✓ | ✓ | ✓ | |
| TaxAgency | ✓ | ✓ | ||||
| Term | ✓ | ✓ | ||||
| TimeActivity | ✓ | ✓ | ✓ | |||
| Transfer | ✓ | ✓ | ✓ | ✓ | ||
| Vendor | ✓ | ✓ | ✓ | ✓ | ||
| VendorCredit | ✓ | ✓ | ✓ |
There are two sets of webhooks: one for live, in-production apps and a separate set for sandbox and testing environments.
You need to set up webhooks for production apps and sandbox environments separately.
After you configure webhook endpoints, we provide an app-specific verifier token. Use verifier tokens to validate the webhook notifications from the callback are from Intuit.
To see verifier tokens:
To use verifier tokens:
Here’s a sample header:
1 2 3 4 5 6 7 8 9 10 | content-length:262 intuit-created-time:2016-02-02T16:25:00-0800 intuit-t-id:9cf50b60-8b0e-4fea-8327-e6a66099fe6f proxy-connection:keep-alive host:sample-endpoint.ilb.idg-notify-ppd.a.intuit.com:8443 intuit-notification-schema-version:0.1 content-type:application/json; charset=utf-8 intuit-signature:6kQBQtjwjupelRMwkyJsnpq80uhz2o+Rn92+m03GhKE= accept:application/json user-agent:intuit_notification_server/0.1 |
Here’s a sample signature verification in Java:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; import java.util.Map; public class VerifySignatureExample { private static final String SIGNATURE = "intuit-signature"; private static final String ALGORITHM = "HmacSHA256"; public boolean isRequestValid(Map<String, String> headers, String payload, String verifier) { String signature = headers.get(SIGNATURE); if (signature == null) { return false; } try { SecretKeySpec secretKey = new SecretKeySpec(verifier.getBytes("UTF-8"), ALGORITHM); Mac mac = Mac.getInstance(ALGORITHM); mac.init(secretKey); String hash = Base64.getEncoder().encodeToString(mac.doFinal(payload.getBytes())); return hash.equals(signature); } catch (NoSuchAlgorithmException | UnsupportedEncodingException | InvalidKeyException e) { return false; } } } |
Webhook notifications are POSTs with a JSON body. The notification payload contains the following fields:
| Field | Description |
|---|---|
specversion |
The version of the CloudEvents specification. Value is always 1. Can be ignored. |
id |
Unique ID of the event. May be useful in troubleshooting or reporting any errors. |
source |
GUID value. Can be ignored. |
type |
Represents the entity and event for the notification, in the format: namespace.entitytype.eventname.version |
datacontenttype |
The content type of the data value: application/json |
time |
The timestamp of when the occurrence happened, provided in RFC 3339 (ISO 8601) format at UTC+0 (e.g., “2018-04-05T03:56:24Z”). |
intuitentityid |
The ID of the entity that was changed. |
intuitaccountid |
The QuickBooks Online company ID or realm ID. |
data |
Name-value pairs containing additional information about the occurrence. Can be ignored if empty. |
Here’s an example notification payload:
1 2 3 4 5 6 7 8 9 10 11 12 13 | [ { "specversion": "1.0", "id": "88cd52aa-33b6-4351-9aa4-47572edbd068", "source": "intuit.dsnBgbseACLLRZNxo2dfc4evmEJdxde58xeeYcZliOU=", "type": "qbo.account.created.v1", "datacontenttype": "application/json", "time": "2025-09-10T21:31:25.179851517Z", "intuitentityid": "1234", "intuitaccountid": "310687", "data": {} } ] |
Webhook events are composed of an array of individual event notifications. Each of these event notifications correspond to unique information associated with a specific realm ID. A single notification can contain a list of events, each for a different QuickBooks Online company/realm ID. Your app must be updated to handle events for multiple companies per notification.
Using the above example, if your app is connected to multiple companies, you will receive an array of event notifications. Each element in this array represents a unique update for a specific company.
Each event notification can include multiple entities such as Customer or Vendor. These entities within the same realm ID denote changes or operations, such as Create, that happened at the given lastUpdated time.