Looking for the previous documentation?Go to v1.docs.pluggy.ai

Credit card transactions and the statement cycle

Why credit card transactions are deleted and re-created with a new id around a statement closing, what identifies a transaction across syncs, and what to reconcile on when there is no stable provider id.

View as Markdown

Credit card data moves more than checking-account data: rows are restated as a bill closes, instalments are re-dated to the cycle they belong to, and pending purchases are confirmed. This page explains what that does to transaction ids and how to reconcile through it.

What identifies a transaction across syncs#

On every sync Pluggy matches the transactions it just collected against the ones it already stored, using a single key:

  • The institution's own transaction id, when the connection provides one.
  • Otherwise, a value derived from the transaction's description, amount, date, and its position among identical transactions on the same day.

The consequence is the important part:

OutcomeWhat you receiveDoes the id survive?
The key matchestransactions/updatedYes — the stored transaction is updated in place.
The key does not matchtransactions/deleted for the old row, transactions/created for the new oneNo — the transaction comes back with a new id.

So a change in the description, amount or date of an already-stored transaction is, by construction, a different transaction. That is why a restatement around a bill closing can arrive as a delete followed by a create rather than as an update.

The ids cannot be preserved, and nothing links the old id to the new one

There is no option to keep the original id across a delete and re-create, and the transactions/deleted payload carries only the ids that were removed — no field points from a deleted transaction to its replacement. Any integration that treats the Pluggy id as a permanent primary key for a credit card transaction will drift.

What to anchor on instead#

providerId — the institution's own transaction id — is the only stable provider-side identifier Pluggy exposes, and it is returned for Open Finance connectors only. On a direct connector it is always null, whatever the institution is.

This matters when the same institution is reachable both ways. Itaú, for example, has both direct connectors and Open Finance ones: a card connected through the direct connector never carries providerId, the same card connected through Open Finance does.

If you have no providerId, reconcile on the transaction's attributes — date + amount + description — as described in Transactions, and keep your own mapping from those attributes to your internal record rather than from the Pluggy id.

See Open Finance vs Direct: field differences for the full list of fields that only one connection type fills.

Practical handling#

  • Process transactions/deleted idempotently. A transaction can disappear in one sync and come back in a later one, so a delete is not necessarily final.
  • Re-fetch rather than infer. After any transaction event, read the current state with GET /transactionsAPI for the affected account instead of reconstructing it from the event stream.
  • Expect the bill window to be wide. Some institutions assign an instalment to a bill months ahead of the purchase, so a credit card transaction dated in the future is not necessarily an error.

If transactions disappear and do not come back

Whether a row stopped being returned by the institution or was dropped during the sync is not something you can tell apart from the API response alone. Open a support ticket with the itemId, the account, and the dates involved, and we can check the execution — see Reporting issues.

Was this page helpful?