Guide
Incremental sync
Transactions and bills change after they first appear: a pending payment books, a category is assigned, a bill is approved and paid. The updatedAfter filter lets you pick up exactly those changes.
The pattern
- Backfill once. Page through
GET /transactions(andGET /bills) with the date range you care about. - Remember a watermark. After each run, store the largest
updatedAtyou saw. - Poll with
updatedAfter. On the next run pass the watermark (minus a small overlap) asupdatedAfter. You get every row created or modified since — and nothing else. - Upsert by
id. Ids are stable for the life of a row, so applying the same page twice is harmless.
bash
# First run: everything since the start of the year
curl "https://api.paygoro.com/v1/transactions?dateFrom=2026-01-01&limit=100" \
-H "Authorization: Bearer $PAYGORO_API_KEY"
# Every later run: only what changed since the newest updatedAt you stored,
# minus a one-minute overlap
curl "https://api.paygoro.com/v1/transactions?updatedAfter=2026-08-30T09:14:00Z&limit=100" \
-H "Authorization: Bearer $PAYGORO_API_KEY"What can change on a row
- Transactions —
statusmoves frompendingtobooked(orrejected/canceled);categoryis set by rules, by Paygoro's enrichment, or by a person, and can be corrected later;merchantNamefills in once enrichment runs. - Bills —
statuswalks the approval and payment lifecycle, extracted fields are corrected by hand,matchedTransactionIdandpaidAtappear once the payment settles.
Practical advice
- Overlap the watermark by a minute. Rows updated in the same second as your previous run are then never missed.
- Poll every 15 minutes or so. Bank data reaches Paygoro on the banks' schedule, typically a few times a day; polling more often mostly spends your rate limit.
- Don't filter by
statuswhile syncing. A transaction that leaves the status you filtered on would then vanish from your feed without a trace. - Treat deletions as absence. v1 has no tombstones; rows are effectively never deleted, but if you need to be certain, a periodic full re-read of a bounded date range is the check.
Outbound webhooks (push notifications for changes) are on the roadmap and will complement, not replace, this pattern. Polling with
updatedAfter will keep working unchanged.