Getting started

Webhook events reference

This is the catalog of every event type Qualy can deliver to a webhook endpoint. Subscribe to only the events your integration needs — you choose them when you register the endpoint.


Event naming

Every event name follows the pattern resource.action, where action is one of create, update, or delete:

  • create — a new object was created.
  • update — an existing object changed (including status transitions like a payment moving from due to paid-full).
  • delete — an object was removed.

A single API request can produce several events. For example, when a customer completes a payment you may receive transactions.create, paymentIntents.update, splitIntents.create, splitIntents.update, and transactions.update. Events are not guaranteed to arrive in order — see event ordering.


Available events

EventFires when
contacts.createA contact is created.
contacts.updateA contact's details change.
paymentIntents.createA payment intent is created.
paymentIntents.updateA payment intent changes — most importantly its status (e.g. duepaid-full, paid-partial, overdue).
paymentIntents.deleteA payment intent is deleted.
transactions.createA transaction is created against a payment intent (a payment attempt begins).
transactions.updateA transaction changes — most importantly its status (e.g. processingsucceeded or failed).
splitIntents.createA payment split is created (the portion of a payment owed to a partner). See payment splits.
splitIntents.updateA payment split changes.
splitIntents.deleteA payment split is removed.
partnerships.createA partnership is created.
partnerships.updateA partnership's details change.

Watch status, not just the event

For payments, the event you almost always care about is a status change carried on paymentIntents.update and transactions.update. Read data.status to decide what to do, rather than assuming an update means "paid-full".


Payload structure

Every delivery has the same envelope. Note this is different from the REST API's data envelope — here data holds the object that changed, and it sits alongside delivery metadata:

FieldDescription
eventThe event type, e.g. transactions.create.
dataThe object that changed. Its shape mirrors that resource's REST representation.
versionAPI version of the payload, e.g. v1.
tenantIdThe Qualy account that generated the event. Useful when one endpoint serves multiple tenants.
messageIdA unique ID for this delivery. Use it to deduplicate and guard against replays.

Example: transactions.create

{
  "event": "transactions.create",
  "data": {
    "_id": "653fc551d14abfe63d4fd48b",
    "paymentIntent": "653fc43fd14abee63d4fcb63",
    "amount": 87700,
    "contact": "65351dfbde8f28fb4a757585",
    "transactionType": "charge",
    "method": "ZAI_PAYTO",
    "currency": "AUD",
    "status": "processing",
    "number": 1906,
    "createdAt": "2023-10-30T15:01:37.187Z"
  },
  "version": "v1",
  "tenantId": "eu1-nonhozilnwbeuo1qkdftdkqg",
  "messageId": "8960447655358365"
}

Example: paymentIntents.update

A status change from due to paid-full:

{
  "event": "paymentIntents.update",
  "data": {
    "_id": "653fc43fd14abee63d4fcb63",
    "status": "paid-full",
    "amount": 100000,
    "due": 0,
    "currency": "AUD",
    "contact": "65351dfbde8f28fb4a757585",
    "number": "2216"
  },
  "version": "v1",
  "tenantId": "eu1-nonhozilnwbeuo1qkdftdkqg",
  "messageId": "8960447655358366"
}

Handling events

Because a single action fans out into several events and they can arrive out of order, treat webhooks as signals to reconcile, not as the source of truth. A robust handler:

  1. Verifies the signature — see verifying signatures.
  2. Deduplicates on messageId — you may receive the same event more than once.
  3. Returns 2xx quickly — acknowledge first, then do the work asynchronously.
  4. Re-fetches the object when it needs the full, current state — for example GET /v1/payment-intents/{id} after a paymentIntents.update.

See Setting up webhooks for the endpoint setup, signature verification, retry behavior, and best practices.

Previous
Setting up webhooks