Skip to main content
GET /v1/clients/{clientCode}/changes lists the changes PayPathIQ has committed for your Integration and Client. Use it to find out what changed after an outage. It needs customers:read, receivables:read, or both.

What an event contains

An event is deliberately small. It names the resource, the kind of change and the accepted revision. It carries no Customer, contact or financial detail.
To see the detail, read the resource with its own GET. That read is authorized when you make it, so a revoked grant or a missing scope cannot recover data through the feed or through an old cursor. Today the feed carries customer.created, customer.updated, receivable.created, receivable.updated, payment_request.created, payment_request.updated, reconciliation.created, reconciliation.updated and payment_delivery.created. A hosted payment request is reported when it is created and each time its status changes (a payer starts a payment, the provider confirms it, or a newer request replaces it); fetch the request for its status. A Receivable lifecycle command, a Payment observation (including a refund or reversal) or a financial correction or raising or clearing a missing-record flag is reported as receivable.updated for each Receivable it changes. A Payment observation that leaves money unapplied is also reported as customer.updated for the paying Customer. A payment reconciliation is reported as reconciliation.created and again as reconciliation.updated when a difference is resolved; recording, matching or holding a receipt line is also reported as receivable.updated for each Receivable it touches. A reported delivery attempt is reported as payment_delivery.created for the Payment request. You only see the events for resource types whose read scope your grant holds. Other resource families will add their own event types when they ship.

Read the feed

  1. Request the feed without a cursor to start at the oldest retained change.
  2. Process every event in data, then store nextCursor.
  3. Send the stored value as cursor on the next request. Keep going while hasMore is true; poll at your own pace when it is false.
nextCursor is always present, including on an empty page. Treat it as opaque. Use limit (1 to 500, default 100) to size pages.

Ordering, duplicates and concurrent writes

  • Events appear in commit order. A change becomes visible only after the mutation that produced it commits, and a rolled-back mutation produces no event. A page never skips a change that commits while you are paginating; you will receive it on a later page.
  • Delivery is at least once. Discard an eventId you have already handled.
  • revision is the resource’s accepted revision at that time. Lifecycle commands do not change it, so two events for one resource can share a revision.

Resynchronize after an expired cursor

Changes are retained for 30 days. A cursor that points before the oldest retained change returns 410 change_cursor_expired. To recover:
  1. Request GET /v1/clients/{clientCode}/changes?from=latest. The response has no events and a nextCursor positioned after every change committed so far.
  2. Read the Customers and Receivables you need.
  3. Resume the feed from the cursor in step 1.
Taking the cursor first means a change that commits while you are reading is delivered by the feed rather than missed. A cursor that was not issued for your Client returns 422 invalid_change_cursor.

Webhooks

The feed is the recovery path for webhooks. A webhook notification carries the same eventId, so you can treat the feed as authoritative and use notifications only to poll sooner.