Overview

Every delivery includes a top-level envelope that wraps the event-specific data object:
FieldTypeDescription
idstringUnique event ID — use this for idempotency (evt_ prefix).
typestringEvent name in resource.action form.
tenantIdstringUUID of the tenant that owns the data.
environmentIdstring | nullID of the environment (live or sandbox). null for tenant-scoped events.
environmentType"live" | "sandbox" | nullHuman-readable environment label.
dataobjectEvent-specific payload — schema documented per event below.
createdAtstringISO 8601 UTC timestamp when Zquence emitted the event.
Your endpoint must return a 2xx HTTP status within 10 seconds. Any non-2xx response or timeout is treated as a failed delivery and retried with exponential backoff. See Retries for the full schedule.

KYC events

KYC events track the internal KYC record lifecycle and provider (Onfido) verification outcomes.

kyc.created

Trigger: A new KYC record is created for a user — happens the first time a user starts the KYC flow. Use cases:
  • Bootstrap a user record in your system.
  • Start a compliance workflow downstream.
  • Log the KYC initiation timestamp.
Payload schema
FieldTypeDescription
kycIdstringInternal KYC record ID.
userIdstringUser the record belongs to.
tenantIdstringOwning tenant.
environmentIdstring | nullEnvironment the record lives in.
currentStepnumberForm step at creation — always 0.
statusstringKYC status at creation — typically an empty string or "pending".
{
  "id": "evt_0b3e2d90d18048eaa913704cd52937b9",
  "type": "kyc.created",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "kycId": "69f9cfbba364e4043805910e",
    "userId": "6a25cdac36bc6230704b5b59",
    "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
    "environmentId": "69f9b5fa0600ccbf9c677005",
    "currentStep": 0,
    "status": "pending"
  },
  "createdAt": "2026-06-07T09:12:41.208Z"
}

kyc.updated

Trigger: The user saves progress on the KYC form — any field update that does not include a final submission signature. Use cases:
  • Track partial form completion for support tooling.
  • Measure drop-off at specific form steps via currentStep.
  • Mirror KYC field changes into your own data store.
Payload schema
FieldTypeDescription
kycIdstringInternal KYC record ID.
userIdstringUser the record belongs to.
tenantIdstringOwning tenant.
environmentIdstring | nullEnvironment.
currentStepnumberForm step the user is on at time of update.
statusstringCurrent KYC status — see KYC status values.
kycDataobjectSpread of clientInformation fields the user has filled in so far.
{
  "id": "evt_1b2595af5e7c4dc4a71bcf54cfe5bc80",
  "type": "kyc.updated",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "kycId": "6a26851e64d94ca57870e73b",
    "userId": "6a267b273efc540f27171829",
    "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
    "environmentId": "69f9b5fa0600ccbf9c677005",
    "currentStep": 5,
    "status": "pending",
    "kycData": {
      "fullName": "James Carter",
      "idNumber": "GB-1234567890",
      "countryOfIssuance": "United Kingdom",
      "corporationName": "Acme Corp"
    }
  },
  "createdAt": "2026-06-08T10:01:31.103Z"
}

kyc.submitted

Trigger: The user completes the KYC form and signs it — submittedOn is set for the first time. This marks the end of user-side data entry. Use cases:
  • Notify your compliance team that a KYC is ready for review.
  • Transition the user to a “pending verification” state in your UI.
  • Trigger downstream document collection workflows.
Payload schema
FieldTypeDescription
kycIdstringInternal KYC record ID.
userIdstringUser the record belongs to.
tenantIdstringOwning tenant.
environmentIdstring | nullEnvironment.
submittedOnstringISO 8601 timestamp when the form was signed and submitted.
statusstringKYC status at submission — typically "pending".
kycDataobjectSpread of clientInformation fields at time of submission.
{
  "id": "evt_aa0593639ead48fc9bd3019d24b54ed0",
  "type": "kyc.submitted",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "kycId": "6a26851e64d94ca57870e73b",
    "userId": "6a267b273efc540f27171829",
    "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
    "environmentId": "69f9b5fa0600ccbf9c677005",
    "submittedOn": "2026-06-08T10:06:15.635Z",
    "status": "pending",
    "kycData": {
      "fullName": "James Carter",
      "idNumber": "GB-1234567890",
      "countryOfIssuance": "United Kingdom",
      "corporationName": "Acme Corp"
    }
  },
  "createdAt": "2026-06-08T10:06:15.684Z"
}

kyc.provider.completed

Trigger: The identity provider (Onfido) returns an approved outcome for the user’s verification run. Use cases:
  • Unlock features or accounts that require verified identity.
  • Update user status to verified in your system.
  • Trigger onboarding completion notifications.
Payload schema
FieldTypeDescription
userIdstringUser whose verification completed.
provider"onfido"Identity provider name. Always "onfido" currently.
statusstringProvider status string — see Provider status values.
workflowRunIdstring | undefinedOnfido workflow run ID. Present when the run is trackable.
{
  "id": "evt_2d5a3f92b04e4e67c4g8f901de23456b",
  "type": "kyc.provider.completed",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "userId": "6a25cdac36bc6230704b5b59",
    "provider": "onfido",
    "status": "complete",
    "workflowRunId": "5d9b5f73-4b43-4d54-8c2c-86c0f8a53f4f"
  },
  "createdAt": "2026-06-07T09:20:11.208Z"
}

kyc.provider.failed

Trigger: The identity provider (Onfido) returns a declined or error outcome for the user’s verification run. Use cases:
  • Flag the user account for manual review.
  • Notify the user that additional steps are required.
  • Track failure rates per reason in your analytics.
Payload schema
FieldTypeDescription
userIdstringUser whose verification failed.
provider"onfido"Identity provider name. Always "onfido" currently.
statusstringProvider failure status — see Provider status values.
workflowRunIdstring | undefinedOnfido workflow run ID. Present when the run is trackable.
{
  "id": "evt_3e6b4g03c15f4f78d5h9g012ef34567c",
  "type": "kyc.provider.failed",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "sandbox",
  "data": {
    "userId": "6a25cdac36bc6230704b5b59",
    "provider": "onfido",
    "status": "declined",
    "workflowRunId": "5d9b5f73-4b43-4d54-8c2c-86c0f8a53f4f"
  },
  "createdAt": "2026-06-07T09:20:11.208Z"
}

KYC status values

The status field in KYC payloads reflects the internal KYC lifecycle state:
ValueMeaning
"" / "pending"KYC record exists but not yet submitted or reviewed.
"approved"KYC passed — provider approved and admin accepted.
"rejected"KYC rejected by admin or provider.
"cancelled"KYC process cancelled.
"locked"Case locked by admin — user cannot edit.

Provider status values

Onfido returns these status strings, mapped to kyc.provider.completed (approved) or kyc.provider.failed (rejected):
ValueOutcome eventMeaning
"complete" / "approved" / "clear"kyc.provider.completedIdentity verified successfully.
"declined" / "rejected"kyc.provider.failedVerification declined by provider.
"abandoned" / "withdrawn"kyc.provider.failedRun abandoned before completion.
"error"kyc.provider.failedProvider-side processing error.
"failed" / "incorrect" / "insufficient" / "expired"kyc.provider.failedDocument or data quality failure.

Account events

Account events cover every stage of an escrow account — from creation and invitation through document submission, admin review, source closures, and case management.
The party key in account payloads depends on accountType. For real_estate accounts the keys are buyer and seller. For all other types (e.g. permanent, construction) the key is customer.

account.created

Trigger: A new escrow account is created by an admin or via the API. The buyer (and optionally seller for real_estate) are linked at creation time. Use cases:
  • Register the account in your system before any parties have accepted.
  • Send a welcome notification to your CRM.
  • Start a compliance timer.
Payload schema
FieldTypeDescription
accountIdstringUnique account ID.
accountTypestringAccount type — "real_estate", "permanent", "construction".
accountTitlestringHuman-readable account title.
tenantIdstringOwning tenant.
environmentIdstring | nullEnvironment.
statusstringAccount status — see Account status values.
customerPartyObject | undefinedPresent for non-real_estate accounts.
buyerPartyObject | undefinedPresent for real_estate accounts.
sellerPartyObject | undefinedPresent for real_estate accounts.
createdAtstringISO 8601 timestamp.
updatedAtstringISO 8601 timestamp.
PartyObject schema
FieldTypeDescription
idstringUser ID of the party.
acceptedbooleanWhether this party has accepted the invitation.
expiresAtstring | nullInvitation token expiry (ISO 8601).
{
  "id": "evt_9998f3a720854483a5c5fdb949638b9d",
  "type": "account.created",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a25cdcc36bc6230704b5bce",
    "accountType": "permanent",
    "accountTitle": "Testing Demo Account",
    "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
    "environmentId": "69f9b5fa0600ccbf9c677005",
    "status": "invited",
    "customer": {
      "id": "6a25cdac36bc6230704b5b59",
      "accepted": false,
      "expiresAt": "2026-06-14T20:00:12.325Z"
    },
    "createdAt": "2026-06-07T20:00:12.414Z",
    "updatedAt": "2026-06-07T20:00:12.414Z"
  },
  "createdAt": "2026-06-07T20:00:12.449Z"
}

account.invited

Trigger: An invitation email is dispatched to a participant. Fires once per party — separately for buyer/customer and seller. Use cases:
  • Log invitation timestamps for compliance audit trails.
  • Track invitation delivery metrics per role.
  • Trigger a parallel onboarding workflow in your system.
Payload schema
FieldTypeDescription
accountIdstringAccount the invitation belongs to.
userIdstringUser who was invited.
emailstringEmail address the invitation was sent to.
namestringDisplay name of the invited user.
role"customer" | "buyer" | "seller"Role of the invited party in this account.
{
  "id": "evt_7a2bc1d304e44091baf1c2de3f4a5678",
  "type": "account.invited",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a25cdcc36bc6230704b5bce",
    "userId": "6a25cdac36bc6230704b5b59",
    "email": "jane@example.com",
    "name": "Jane Smith",
    "role": "customer"
  },
  "createdAt": "2026-06-07T20:00:12.460Z"
}

account.opened

Trigger: A participant clicks their invitation link and the invitation page loads. The party has not yet accepted — this is a view event, not an acceptance event. Use cases:
  • Detect when a party has seen the invitation (engagement tracking).
  • Start a follow-up timer if acceptance does not follow within N hours.
  • Audit trail for compliance.
Payload schema
FieldTypeDescription
accountIdstringAccount whose invitation was opened.
role"customer" | "buyer" | "seller"Role of the party who opened the link.
openedAtstringISO 8601 timestamp when the link was opened.
{
  "id": "evt_2a3bc4d5e6f74812abc0d1ef2a3b4c5d",
  "type": "account.opened",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a1ea31b892791af056f46bd",
    "role": "buyer",
    "openedAt": "2026-06-02T09:45:11.108Z"
  },
  "createdAt": "2026-06-02T09:45:11.109Z"
}

account.accepted

Trigger: A participant accepts the invitation. For real_estate accounts, fires once per party (buyer and seller independently). Account status advances to "accepted" only when all required parties have accepted. Use cases:
  • Gate access to document upload flows until all parties accept.
  • Notify stakeholders when a party joins.
  • Progress a workflow state machine.
Payload: Full account snapshot — same schema as account.created with updated accepted flag and status.
{
  "id": "evt_4c5de6f7a8b94c23bcd1e2fg3h4i5j6k",
  "type": "account.accepted",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a25cdcc36bc6230704b5bce",
    "accountType": "permanent",
    "accountTitle": "Testing Demo Account",
    "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
    "environmentId": "69f9b5fa0600ccbf9c677005",
    "status": "accepted",
    "customer": {
      "id": "6a25cdac36bc6230704b5b59",
      "accepted": true,
      "expiresAt": "2026-06-14T20:00:12.325Z"
    },
    "createdAt": "2026-06-07T20:00:12.414Z",
    "updatedAt": "2026-06-07T20:10:45.000Z"
  },
  "createdAt": "2026-06-07T20:10:45.012Z"
}

account.status.changed

Trigger: The account status transitions to any new value. Fires on admin close, admin reopen, and when both parties accept. Use cases:
  • Drive a workflow state machine (e.g. move to "completed" after close).
  • Send status update emails to participants.
  • Update your internal CRM or compliance dashboard.
Payload: Full account snapshot — same schema as account.created with the new status. Account status values
ValueMeaning
"invited"Account created; invitations sent. No party has accepted yet.
"pending"At least one party has accepted; waiting on remaining parties.
"accepted"All required parties have accepted. Documents can now be submitted.
"completed"Admin has closed the account after all sources are verified.
{
  "id": "evt_5d6ef7a8b9c04d34cde2f3gh4i5j6k7l",
  "type": "account.status.changed",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a25cdcc36bc6230704b5bce",
    "accountType": "permanent",
    "accountTitle": "Testing Demo Account",
    "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
    "environmentId": "69f9b5fa0600ccbf9c677005",
    "status": "completed",
    "customer": {
      "id": "6a25cdac36bc6230704b5b59",
      "accepted": true,
      "expiresAt": "2026-06-14T20:00:12.325Z"
    },
    "createdAt": "2026-06-07T20:00:12.414Z",
    "updatedAt": "2026-06-07T21:00:00.000Z"
  },
  "createdAt": "2026-06-07T21:00:00.015Z"
}

account.archived

Trigger: An admin archives the account. Archived accounts are read-only — no modifications are permitted until unarchived. Use cases:
  • Move the account to an archived view in your dashboard.
  • Suppress notifications for archived accounts.
  • Audit who archived what and when.
Payload schema
FieldTypeDescription
accountIdstringID of the archived account.
archivedBystringUser ID of the admin who archived the account.
{
  "id": "evt_6e7fg8h9i0j14e45def3g4hi5j6k7l8m",
  "type": "account.archived",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a1ea31b892791af056f46bd",
    "archivedBy": "69f9cfbba364e4043805910e"
  },
  "createdAt": "2026-06-02T10:02:04.300Z"
}

account.unarchived

Trigger: An admin restores a previously archived account. The account becomes editable again. Use cases:
  • Restore the account to the active view in your dashboard.
  • Re-enable downstream notifications and workflows.
Payload schema
FieldTypeDescription
accountIdstringID of the unarchived account.
unarchivedBystringUser ID of the admin who unarchived the account.
{
  "id": "evt_7f8gh9i0j1k24f56efg4h5ij6k7l8m9n",
  "type": "account.unarchived",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a1ea31b892791af056f46bd",
    "unarchivedBy": "69f9cfbba364e4043805910e"
  },
  "createdAt": "2026-06-02T11:05:00.300Z"
}

account.deleted

Trigger: An admin permanently deletes an account. This also cascades to delete all associated document review files. This action is irreversible. Use cases:
  • Hard-delete the account record from your system.
  • Clean up downstream references (CRM entries, linked workflows).
  • Emit a GDPR deletion audit record.
Payload schema
FieldTypeDescription
accountIdstringID of the deleted account.
accountTypestringAccount type at time of deletion.
statusstringAccount status at time of deletion.
{
  "id": "evt_2efb0dbf1b9042a6bdc050c6ee2f8375",
  "type": "account.deleted",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a1ea31b892791af056f46bd",
    "accountType": "real_estate",
    "status": "invited"
  },
  "createdAt": "2026-06-02T10:02:04.300Z"
}

account.document.submitted

Trigger: A user submits their documents for admin review (submitForReview: true). Fires on both initial submission and re-submission after corrections. Use cases:
  • Notify the compliance team that documents are ready to review.
  • Start a review SLA timer.
  • Transition the account to "under_review" in your system.
Payload schema
FieldTypeDescription
accountIdstringAccount the documents belong to.
userIdstringUser who submitted the documents.
statusstringDocument record status after submission — typically "under_review".
submittedAtstring | nullISO 8601 timestamp of the submission.
{
  "id": "evt_7f8g9h0i1j2k3l4m5n6o7p8q",
  "type": "account.document.submitted",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "accountId": "6a1ea31b892791af056f46bd",
    "userId": "6a25cdac36bc6230704b5b59",
    "status": "under_review",
    "submittedAt": "2026-06-08T10:06:15.635Z"
  },
  "createdAt": "2026-06-08T10:06:15.684Z"
}

account.document.reviewed

Trigger: An admin approves or rejects a specific document. Fires once per document decision. Use cases:
  • Notify the user their document was approved or needs correction.
  • Update a document status badge in your portal.
  • Track review turnaround times per document type.
Payload schema
FieldTypeDescription
reviewIdstringInternal document review record ID.
accountIdstringAccount the document belongs to.
userIdstringUser who owns the document.
documentCodestringDot-notation path identifying the document field (e.g. "bankStatement.statementS3Key").
displayNamestringHuman-readable document name (e.g. "Bank Statement").
status"approved" | "rejected"Admin decision.
feedbackstring | nullRejection reason or admin note. null if approved.
{
  "id": "evt_8g9h0i1j2k3l4m5n6o7p8q9r",
  "type": "account.document.reviewed",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "reviewId": "6a26851e64d94ca57870e73c",
    "accountId": "6a1ea31b892791af056f46bd",
    "userId": "6a25cdac36bc6230704b5b59",
    "documentCode": "bankStatement.statementS3Key",
    "displayName": "Bank Statement",
    "status": "approved",
    "feedback": null
  },
  "createdAt": "2026-06-08T10:10:00.123Z"
}

account.document.requested

Trigger: An admin requests an additional document from the user. Use cases:
  • Notify the user a specific document has been requested.
  • Add a pending task to the user’s document checklist in your UI.
  • Track admin-initiated document requests separately from standard requirements.
Payload schema
FieldTypeDescription
reviewIdstringInternal document review record ID created for this request.
userIdstringUser the document is being requested from.
documentCodestringDot-notation code for the requested document (e.g. "requested.proof_of_address").
displayNamestringHuman-readable name of the requested document.
notestring | nullInstructions the admin provided along with the request.
{
  "id": "evt_9h0i1j2k3l4m5n6o7p8q9r0s",
  "type": "account.document.requested",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "reviewId": "6a26851e64d94ca57870e73d",
    "userId": "6a25cdac36bc6230704b5b59",
    "documentCode": "requested.proof_of_address",
    "displayName": "Proof of Address",
    "note": "Please upload a utility bill or bank statement dated within the last 3 months."
  },
  "createdAt": "2026-06-08T10:12:00.456Z"
}

account.case.locked

Trigger: An admin locks the user’s case. While locked, the user cannot upload documents or take any document action. Use cases:
  • Prevent further user activity while a compliance review is in progress.
  • Display a “case locked” banner in your portal.
  • Log the lock event with actor identity for audit trails.
Payload schema
FieldTypeDescription
userIdstringUser whose case was locked.
accountIdstringMost recent account associated with this user.
accountTitlestringTitle of that account.
lockedBystringEmail or identifier of the admin who performed the lock.
lockedAtstringISO 8601 timestamp of the lock action.
{
  "id": "evt_1j2k3l4m5n6o7p8q9r0s1t2u",
  "type": "account.case.locked",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "userId": "6a267b273efc540f27171829",
    "accountId": "6a1ea31b892791af056f46bd",
    "accountTitle": "Testing Demo Account",
    "lockedBy": "admin@example.com",
    "lockedAt": "2026-06-08T10:20:00.000Z"
  },
  "createdAt": "2026-06-08T10:20:00.012Z"
}

account.case.unlocked

Trigger: An admin unlocks a previously locked case. The user can resume document uploads. Use cases:
  • Remove the “case locked” banner in your portal.
  • Re-enable document upload flows for the user.
  • Log who unlocked the case and when.
Payload schema
FieldTypeDescription
userIdstringUser whose case was unlocked.
accountIdstringMost recent account associated with this user.
accountTitlestringTitle of that account.
unlockedBystringEmail or identifier of the admin who unlocked the case.
unlockedAtstringISO 8601 timestamp of the unlock action.
{
  "id": "evt_2k3l4m5n6o7p8q9r0s1t2u3v",
  "type": "account.case.unlocked",
  "tenantId": "bc41c6ab-7206-4033-b632-4d1cfa86d840",
  "environmentId": "69f9b5fa0600ccbf9c677005",
  "environmentType": "live",
  "data": {
    "userId": "6a267b273efc540f27171829",
    "accountId": "6a1ea31b892791af056f46bd",
    "accountTitle": "Testing Demo Account",
    "unlockedBy": "admin@example.com",
    "unlockedAt": "2026-06-08T11:00:00.000Z"
  },
  "createdAt": "2026-06-08T11:00:00.015Z"
}

Pattern matching

Subscribe to individual events or entire namespaces:
PatternMatches
kyc.submittedExactly kyc.submitted
kyc.provider.*kyc.provider.completed and kyc.provider.failed
kyc.*All five KYC events
account.document.*account.document.submitted, account.document.reviewed, account.document.requested
account.source.*account.source.closed and account.source.reopened
account.case.*account.case.locked and account.case.unlocked
account.*All 14 account events
*Every event across all namespaces

Delivery response codes

Zquence interprets your endpoint’s HTTP response as follows:
Your responseZquence behaviour
2xx (200–299)Delivery marked success. No retry.
4xx / 5xxDelivery marked failed. Retried with exponential backoff while attempts remain.
Timeout (> 10 s)Delivery marked failed. Retried with exponential backoff while attempts remain.
Connection refusedDelivery marked failed. Retried.
Even 400 Bad Request and 403 Forbidden are treated as failures and retried. Your handler should return 200 and discard events it does not recognise rather than returning 4xx.
To safely handle duplicate deliveries (from retries or manual replays), store event.id in a deduplication table with a TTL of at least 7 days and skip processing if the ID is already present.