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}/transactionsThis 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:
| List | Included transactions | Filtered / ordered on | Pagination |
|---|---|---|---|
pending | Transactions in status authorization | transactionTime | None — always returned in full |
posted | Settled (“booked”) transactions in status financial | postingTime (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
| Parameter | Type | Description |
|---|---|---|
accountId | string | The account identifier |
Query Parameters
| Parameter | Type | Description |
|---|---|---|
limit | number | Maximum posted transactions to return (max 500, default 100). Does not apply to pending, which is always returned in full |
from | datetime | Include only transactions strictly after this ISO-8601 timestamp |
to | datetime | Include only transactions strictly before this ISO-8601 timestamp |
cursor | string | Opaque 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.
- Make the first request without a
cursor. The response contains the fullpendinglist and the first page ofpostedtransactions. - If the response contains a
nextCursor, more posted results may exist. Re-issue the same request — identicalfrom,to, andlimit— with thecursorquery parameter set to that exact value to fetch the next page ofpostedtransactions. - Repeat until the response no longer contains a
nextCursor, at which point thepostedlist 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:
| Field | Type | Description |
|---|---|---|
limit | number | The posted limit requested |
from | datetime | The from date requested (if any) |
to | datetime | The to date requested (if any) |
nextCursor | string | Present when more posted results may exist. Pass it back as cursor to fetch the next page. Absent when done |
pending | Transaction[] | Transactions in status authorization, filtered by transactionTime. Always returned in full (not paginated) |
posted | Transaction[] | 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
pendingon one request, then - in
postedon 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
pendingreappears inposted, update the stored record in place (newstatus,postingTime,billingAmount,accountBalanceAfterTransaction, and other enriched fields) instead of inserting a duplicate. - When you persist a
pendingtransaction, verify its outcome withGET /accounts/{accountId}/transactions/{transactionId}: it returns the currentstatusfor thatidplus adeletedflag, so you can confirm whether the transaction posted or failed instead of waiting for it to (possibly never) reappear inposted.
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
| Endpoint | Required Scope |
|---|---|
GET /v2/accounts/{accountId}/transactions | PSP_AI |
Error Handling
| Status | Description |
|---|---|
400 | Invalid request parameters |
403 | The access token was not found or grants no access |
404 | The account is not found or not accessible to the token |
500 | Internal server error |
Error responses include an errorCode and message for debugging.