Skip to Content
API OverviewAccountsTransactions v2

Transactions v2

The Transactions v2 endpoint returns an account’s transactions split into two separate lists — pending and posted — following the NextGen (Berlin Group) convention of distinguishing authorized-but-not-yet-settled activity from settled bookings. This makes it easier to reconcile authorizations against booked entries without inspecting each transaction’s status.

This endpoint requires the PSP_AI (Account Information) scope.

GET /v2/accounts/{accountId}/transactions

This is an additive alternative to the flat GET /accounts/{accountId} /transactions list. The v1 endpoint is unchanged and remains available. Both return the same Transaction objects.

Pending vs. posted

The two lists are produced by two independent queries:

ListIncluded transactionsFiltered / ordered onPagination
pendingTransactions in status authorizationtransactionTimeNone — always returned in full
postedSettled (“booked”) transactions in status financialpostingTime (the financial time)Limited by limit, paged via cursor

Only the posted list is limited and paginated. The pending list is returned in full on every response — limit and cursor do not apply to it. Pending transactions are inherently few (only those still in authorization), so there is no need to page through them.

Path Parameters

ParameterTypeDescription
accountIdstringThe account identifier

Query Parameters

ParameterTypeDescription
limitnumberMaximum posted transactions to return (max 500, default 100). Does not apply to pending, which is always returned in full
fromdatetimeInclude only transactions strictly after this ISO-8601 timestamp
todatetimeInclude only transactions strictly before this ISO-8601 timestamp
cursorstringOpaque pagination cursor for the posted list. Omit on the first request; pass a nextCursor from a previous response thereafter

The from/to window is applied per list on the column that list is ordered on (transactionTime for pending, postingTime for posted). limit and cursor apply only to the posted list — the pending list is always returned in full and is unaffected by them.

If you send a date without a time component (e.g., 2025-01-01), it defaults to 2025-01-01T12:00:00.000.

Cursor pagination

Pagination applies only to the posted list and uses an opaque cursor rather than an offset. The pending list is returned in full on the first response and is not repeated on subsequent pages.

  1. Make the first request without a cursor. The response contains the full pending list and the first page of posted transactions.
  2. If the response contains a nextCursor, more posted results may exist. Re-issue the same request — identical from, to, and limit — with the cursor query parameter set to that exact value to fetch the next page of posted transactions.
  3. Repeat until the response no longer contains a nextCursor, at which point the posted list has been fully returned.

The cursor tracks the posted list’s position, so pages produced this way never overlap — no client-side de-duplication is required. Keep from, to, and limit stable across a pagination sequence; changing them invalidates the cursor’s meaning.

Because pending is returned in full on the first request, use the pending list from that first response and ignore it on subsequent paged requests.

Response Structure

The response is a TransactionsResponseV2 object:

FieldTypeDescription
limitnumberThe posted limit requested
fromdatetimeThe from date requested (if any)
todatetimeThe to date requested (if any)
nextCursorstringPresent when more posted results may exist. Pass it back as cursor to fetch the next page. Absent when done
pendingTransaction[]Transactions in status authorization, filtered by transactionTime. Always returned in full (not paginated)
postedTransaction[]Settled transactions in status financial, filtered by postingTime. Limited and paginated

Each entry in pending and posted is a full Transaction object — including the optional attachmentIds array when the user has added attachments to the transaction.

Example

{ "limit": 100, "from": "2025-01-01T00:00:00.000Z", "to": "2025-02-01T00:00:00.000Z", "nextCursor": "eyJwb3N0ZWQiOjEwMH0=", "pending": [ { "id": "txn-a1", "status": "authorization", "transactionTime": "2025-01-31T18:22:00.000Z", "billingAmount": { "amount": -149.0, "currency": "DKK" }, "title": "Coffee Shop", "type": "card", "accountId": "account-uuid" } ], "posted": [ { "id": "txn-b2", "status": "financial", "transactionTime": "2025-01-28T09:10:00.000Z", "postingTime": "2025-01-29T02:00:00.000Z", "billingAmount": { "amount": 500.0, "currency": "DKK" }, "title": "Salary", "type": "domesticCreditTransfer", "accountId": "account-uuid", "attachmentIds": ["attachment-1", "attachment-2"] } ] }

Eventual consistency

The pending/posted split reflects a point in time, not a fixed classification. A transaction that appears in pending (status authorization) will, once it settles, transition to status financial, gain a postingTime, and move into the posted list. This transition can happen on the same day or days later, depending on the product and settlement path.

Because of this, the same transaction can appear:

  • in pending on one request, then
  • in posted on a later request (once it has settled).

Once a transaction has moved to posted, it stays there — posted is the terminal designation. It will not move back to pending.

Not every pending transaction settles. A transaction in pending may fail (for example a declined or reversed authorization) and never transition to posted. It will simply stop appearing in pending without ever showing up in posted. Because of this, do not assume a pending transaction will eventually become posted.

To tell a failed-and-removed transaction apart from one you simply have not re-fetched, use the GET /accounts/{accountId}/transactions/{transactionId} endpoint: it keeps returning the transaction by its stable id and sets deleted: true once the transaction has been removed. That is the definitive signal that a pending transaction failed, rather than waiting for it to (possibly never) reappear in posted. See Detecting deleted transactions.

The transaction id is stable across this transition — it does not change when a transaction moves from pending to posted. Use it to match and update a transaction you already stored rather than treating the posted entry as a new record:

  • Key your local store on id.
  • When a transaction you previously saw in pending reappears in posted, update the stored record in place (new status, postingTime, billingAmount, accountBalanceAfterTransaction, and other enriched fields) instead of inserting a duplicate.
  • When you persist a pending transaction, verify its outcome with GET /accounts/{accountId}/transactions/{transactionId}: it returns the current status for that id plus a deleted flag, so you can confirm whether the transaction posted or failed instead of waiting for it to (possibly never) reappear in posted.

This mirrors the eventual consistency behaviour of the flat transaction list: fields are enriched over time and the same id can return different payloads on repeat fetches. Poll recent activity rather than assuming a single response is complete for “today”.

Required Scope

EndpointRequired Scope
GET /v2/accounts/{accountId}/transactionsPSP_AI

Error Handling

StatusDescription
400Invalid request parameters
403The access token was not found or grants no access
404The account is not found or not accessible to the token
500Internal server error

Error responses include an errorCode and message for debugging.

Last updated on