Skip to main content
A Transaction represents a single line item on a bank account as reported by the institution. Transactions are read-only and are populated automatically during connection syncs.

Status lifecycle

StatusMeaning
pendingAuthorised but not yet settled. Amount or details may still change.
postedFully settled.
reversedPreviously posted transaction that was reversed.
cancelledPending item that was voided before settlement.
unknownThe bank provided a state that does not yet map cleanly to a richer public status.
The current public implementation mainly emits pending and posted; the remaining values are reserved for broader coverage.

Two ways to read transactions

Historical browse — GET /v1/transactions

Use this endpoint for backfills, date-range queries, and reconciliation views. It supports filtering by accountId, connectionId, status, rail, postedDateGte, and postedDateLt. Results are cursor-paginated and can be sorted by postedDate or updatedAt. List cursors are valid only for the same query and sort order. They are not interchangeable with sync cursors.

Incremental sync — GET /v1/transactions/sync

Use this endpoint to maintain a current mirror of transactions over time. The sync stream returns change events ordered by the server’s sync cursor ascending, not by postedDate or raw updatedAt.
This is not the endpoint for fetching existing transactions, and it does not return your transaction history. The first call (without a cursor) returns zero events by design — it only establishes your stream head. Load historical data from GET /v1/transactions, then use sync for changes from that point on.

No-gap bootstrap

  1. Call GET /v1/transactions/sync without a cursor. This returns no events — its only purpose is to establish the stream head.
  2. Save the returned nextCursor as your stream head.
  3. Backfill historical data from GET /v1/transactions.
  4. Resume polling GET /v1/transactions/sync from the saved cursor.
  5. If hasMore is true, call again immediately with the returned nextCursor.
Duplicates between the backfill and later sync pages are expected. Reconcile by stable transaction.id.
Persist nextCursor only after the full page has been durably applied. If a sync call is retried, reuse the same cursor.

Empty responses are normal

A sync call that returns zero events means nothing has changed in that stream since your cursor — keep the same cursor and poll again later. Sync does deliver transactions: once data is created or changes, it arrives as added and modified events on the next poll. A zero-event response simply means there is nothing new since your cursor; it does not mean the connection has no transactions. Use GET /v1/transactions to read transactions that already exist (your historical set), and sync to stay up to date from there. If you expect changes but consistently see zero events, confirm you are polling with the cursor you saved and the same stream-defining filters you bootstrapped with (see below).

Sync event types

Event typeHow to handle it
addedUpsert the embedded transaction by transaction.id.
modifiedUpsert the embedded transaction by transaction.id.
removedDelete the referenced transaction id from your current mirror.
removed currently represents transaction deletions. Account visibility changes without transaction mutations are intentionally out of scope for the current sync stream.

Cursor and retry rules

  • Sync cursors are valid only for the same stream-defining filters: accountId and connectionId. If you bootstrap with connectionId, keep polling with that same connectionId (the same applies to accountId).
  • Sparse fields= selections do not change stream membership and are not part of cursor compatibility.
  • Sync cursors expire after 90 days.
  • invalid_cursor means the cursor is malformed or does not match the filter set. Changing the filters between bootstrap and polling returns this error — it does not silently fall back to zero events. Rebootstrap with the original filters.
  • cursor_expired means you need to rebootstrap from scratch.
  • If rate limited, honor Retry-After when present and retry with the same cursor.

Key fields and rails

  • amount — Signed decimal string. Positive = inflow, negative = outflow.
  • entryTypecredit or debit, as reported by the bank.
  • rail — Payment rail such as internalTransfer, card, ach, sepaCredit, sepaDebit, wire, swift, fasterPayments, check, cash, crypto, other, or unknown.
  • paymentReference — Remittance reference for reconciliation (e.g. invoice number).
  • bankReference — Bank-assigned operational tracking ID.
  • counterpartyName / counterpartyAccountMasked — Available on many rail types.
Waycore can notify you through the transactions.sync_available webhook when fresh data is ready, so you do not need to poll blindly. Treat that webhook as a prompt to call GET /v1/transactions/sync, not as a replacement for the sync stream itself.

Endpoints

List transactions

Sync transactions

Get transaction

Required scopes

ScopeUsed by
transactions:readList, sync, get