Accounts API
The Accounts API allows Third Party Providers (TPPs) to access account information on behalf of authorized users. This API requires the PSP_AI (Account Information) scope.
Capabilities
List Accounts
Retrieve a list of all accounts accessible to the authenticated user.
GET /accountsEach account includes:
| Field | Required | Description |
|---|---|---|
id | Yes | Unique account identifier used in other API calls |
name | Yes | Human-readable account name |
currency | Yes | Account currency (ISO 4217 alpha-3, e.g., DKK, SEK, NOK) |
bban | Yes | National Basic Bank Account Number |
iban | No | International Bank Account Number |
swift | No | SWIFT/BIC code |
balanceAmount | Yes | Current account balance |
balanceReservedAmount | Yes | Amount reserved for pending transactions |
balanceAvailableAmount | Yes | Available spending amount (balance + credit limit - reserved) |
creditLimitAmount | No | Authorized credit limit (if applicable) |
type | Yes | Account type (only CHECKING accounts are available via PSD2) |
supportsPayments | Yes | Whether payments can be initiated from this account |
supportsTransfers | Yes | Whether credit transfers can be initiated from this account |
ownerName | No | Full name of the account owner |
usage | No | Whether the account is owned by a private individual or an organisation. One of PRIVATE, ORGANISATION. Omitted if the owner type cannot be determined. |
Only checking accounts are exposed through the Open Banking API. Savings accounts and other account types are not accessible.
List Transactions
Retrieve transaction history for a specific account.
GET /accounts/{accountId}/transactionsQuery Parameters
| Parameter | Type | Description |
|---|---|---|
limit | number | Maximum transactions to return (max 500, default 100) |
offset | number | Pagination offset for retrieving additional pages |
from | datetime | Include only transactions after this ISO-8601 timestamp |
to | datetime | Include only transactions before this ISO-8601 timestamp |
If you send a date without a time component (e.g., 2025-01-01), it defaults
to 2025-01-01T12:00:00.000.
Response Structure
The response is a TransactionsResponse wrapper object:
| Field | Type | Description |
|---|---|---|
offset | number | The offset used in pagination |
limit | number | The limit requested |
from | datetime | The from date requested (if any) |
to | datetime | The to date requested (if any) |
transactions | Transaction[] | Array of transaction objects |
The offset is the amount of transactions “skipped”, if you have 10 transactions, and limit is 10 and you have offset 1 you get the last 9 transactions.
Transaction Properties
Each transaction includes:
| Field | Description |
|---|---|
id | Unique transaction identifier |
transactionTime | ISO-8601 timestamp when the transaction was initiated (e.g., the moment a card was swiped or a transfer was created). Present on all transactions including pending ones |
postingTime | ISO-8601 timestamp when the transaction was settled and funds were moved on the account. null for pending/authorized transactions that have not yet settled |
billingAmount | Amount object ({ amount, currency }) — the actual billed amount in the account’s currency |
transactionAmount | Amount object ({ amount, currency }) — the original transaction amount (may differ for foreign currency). Can be null in cases where the payment was never reserved on the account |
currencyExchange | CurrencyExchange object with currency (string), targetCurrency (string), and exchangeRate (number) |
title | Transaction description |
type | Transaction type: dkPaymentSlip, domesticCreditTransfer, card, direct-debit, or unknown |
domesticCreditTransferInfo | Object with recipientBBAN (string, BBAN of the recipient, 11-14 chars) and message (string, optional). Present for domestic credit transfer transactions |
cardTransactionInfo | Object with merchantName (string) and merchantCategoryCode (number). Present for card transactions |
status | Status: future, financial, authorization, interim, failed_authorization, declined, initiated, or unknown |
accountId | Parent account identifier |
message | Optional free-text payment message associated with the transaction — for example, the sender note on a transfer, the message on a direct debit, or the description on a Swedish giro payment. Present when available; omitted otherwise. |
debtor | TransactionParty object ({ name, address, account?: { scheme, identification }, bic? }) — the party funds are debited from. Populated for transfer-like transactions. |
creditor | TransactionParty object ({ name, address, account?: { scheme, identification }, bic? }) — the party funds are credited to. Populated for transfer-like transactions. |
accountBalanceAfterTransaction | Amount object — the booked account balance after this transaction settled. Populated for settled transactions; omitted otherwise. |
additionalInformation | object (string map) — free-form identifiers that don’t fit other fields. See below for currently emitted keys. |
Transactions are returned with negative amounts for debits and positive amounts for credits.
Billing amount vs. transaction amount
A transaction carries two amount fields:
transactionAmount— the amount in the original currency of the payment (e.g., EUR 20 for a purchase at a European shop). Can benullin some special cases for example when the payment was never reserved on the account, such as certain direct settlements.billingAmount— the amount that was actually posted to the account, in the currency of the posting. For foreign-currency transactions this is the converted amount after exchange.
When both currencies are the same, the two values will match. When they differ, the currencyExchange object provides the conversion details.
Always prefer billingAmount — it is the authoritative figure for balance
calculations and represents what actually entered or left the account.
Example: A card payment made for 20 EUR:
{
"billingAmount": { "amount": -149.0, "currency": "DKK" },
"transactionAmount": { "amount": -20.0, "currency": "EUR" },
"currencyExchange": {
"currency": "EUR",
"targetCurrency": "DKK",
"exchangeRate": 7.45
}
}Mapping properties for transaction fields
Here is a mapping of our statuses, to codes of the ISO 20022 data table:
| Lunar Status | Closest ISO 20022 | Rationale |
|---|---|---|
initiated | RCVD / PDNG | Transaction received/pending |
authorization | ACTC / PDNG | Awaiting authorization |
interim | ACSP | In process, not yet settled |
financial | ACSC / ACCC | Settled/completed |
future | PDNG | Scheduled for a future date |
failed_authorization | RJCT | Authorization failed |
declined | RJCT | Rejected |
unknown | — | A fault that isn’t described above, contact Lunar |
Mapping to NextGenPSD2 (Berlin Group) fields:
Lunar uses transactionTime and postingTime as full ISO-8601 timestamps. The NextGenPSD2 spec uses bookingDate, valueDate, and transactionDate as date-only (ISODate) fields. The mapping between them depends on the transaction status:
bookingDate — “The date when an entry is posted to an account on the ASPSP’s books.”
- Maps to
postingTime. Both represent when the transaction was recorded on the account. nullfor pending transactions, just asbookingDateis absent for pending entries in NextGen.
valueDate — “The date at which assets become available to the account owner in case of a credit, or cease to be available in case of a debit. If entry status is pending, refers to an expected/requested value date.”
- For settled transactions (
financialstatus): maps topostingTime. Lunar does not distinguish between the booking date and the value date — settlement, booking, and funds availability happen at the same time. - For future/scheduled transactions (
futurestatus): maps totransactionTime, which holds the scheduled execution date — equivalent to the “expected/requested value date” in NextGen. - For other pending transactions (
authorization,interim,initiated): Lunar does not expose an expected value date. There is no direct equivalent.
transactionDate (NextGen card transactions only) — “Date of the actual card transaction.”
-
Maps to
transactionTime. Both represent when the transaction was initiated (e.g., the moment a card was swiped or a transfer was created).Reconciliation guidance:
-
Use
postingTimefor matching against bank statements and cash-flow reconciliation — this is when the account balance actually changed. It corresponds tobookingDatein NextGenPSD2. -
Use
transactionTimeto determine when the transaction was initiated, e.g., for dispute timelines or user-facing activity logs. -
For pending transactions (
authorization,interim,initiated), onlytransactionTimeis available.postingTimeis populated once the transaction reachesfinancialstatus. -
For future/scheduled transactions,
transactionTimerepresents the expected execution date and can be used as an anticipated settlement date.
Debtor and creditor parties
Transfer-like transactions (domestic credit transfers, international payments, direct debits, bank giro, plus giro, Swish, e-faktura) carry structured debtor and creditor objects. The direction follows the sign of billingAmount:
- Incoming (positive
billingAmount) — the counterparty is the debtor (the sender); the account holder is the creditor. - Outgoing (negative
billingAmount) — the account holder is the debtor; the counterparty is the creditor.
All fields on the party object are optional. Consumers must not rely on any particular field being present.
| Field | Required | Description |
|---|---|---|
name | No | Name of the party. |
address | No | Address of the party. |
account | No | Structured account identifier (see below). |
bic | No | SWIFT/BIC of the counterparty bank. |
When account is present, both scheme and identification are guaranteed:
account.scheme | Description |
|---|---|
IBAN | International Bank Account Number (ISO 13616). |
BBAN | National Basic Bank Account Number, used for domestic transfers in DK, NO, and SE. |
ACCOUNT_NUMBER | Fallback for account identifiers that are neither an IBAN nor a BBAN. Treat as opaque. |
Additional schemes may be introduced in the future; consumers should treat unknown values defensively.
When the counterparty’s account identifier is not a bank account (e.g. bank giro, plusgiro, Swish), the account field is omitted and the relevant identifier is surfaced via additionalInformation instead.
Example: An incoming domestic credit transfer of DKK 500:
{
"billingAmount": { "amount": 500.0, "currency": "DKK" },
"debtor": {
"name": "Jane Doe",
"account": { "scheme": "BBAN", "identification": "12345678901" }
},
"creditor": {
"name": "John Smith",
"account": { "scheme": "BBAN", "identification": "98765432109" }
}
}Example: An outgoing international payment to a Danish IBAN:
{
"billingAmount": { "amount": -1000.0, "currency": "DKK" },
"creditor": {
"name": "Foreign Recipient",
"account": { "scheme": "IBAN", "identification": "DK1212345678901234" },
"bic": "BANKDKKKXXX"
}
}Account balance after transaction
accountBalanceAfterTransaction carries the booked account balance immediately after a transaction settled, as an Amount object ({ amount, currency }). It is populated for settled transactions and omitted otherwise.
This field aligns with Berlin Group’s balanceAfterTransaction and is useful for reconstructing a running balance from a transaction list without a separate balance call.
Additional information map
additionalInformation is a free-form string-to-string map for identifiers that don’t fit other structured fields. It is omitted when empty. Consumers should treat unrecognized keys as opaque — new keys may be added without a version bump.
Currently emitted keys:
| Key | Description |
|---|---|
bgNumber | Swedish bank giro recipient number |
pgNumber | Swedish plusgiro recipient number |
giroNumber | Generic giro identifier from e-faktura SE (may be a BG or PG number; not distinguishable at source) |
bgIssuer | Bank giro issuer identifier (BGS number) from e-faktura SE |
ocr | OCR reference for SE bank giro / plusgiro / e-faktura |
swishId | Swish payment identifier |
Get Transaction by ID
Retrieve a single transaction by its identifier.
GET /accounts/{accountId}/transactions/{transactionId}Path Parameters
| Parameter | Type | Description |
|---|---|---|
accountId | string | The account identifier |
transactionId | string | The transaction identifier |
Headers
| Header | Required | Description |
|---|---|---|
X-Language | No | Language preference |
Returns a single Transaction object (same structure as in the list endpoint).
Funds Confirmation
Check whether a specific amount is available in an account. This is useful before initiating a payment to ensure it won’t fail due to insufficient funds.
GET /funds-confirmationRequest Body
{
"accountId": "account-uuid",
"amount": 100.0,
"currency": "DKK"
}Response
{
"fundsAvailable": true
}Funds confirmation requires the PSP_PI (Payment Initiation) scope, not
PSP_AI.
Required Scopes
| Endpoint | Required Scope |
|---|---|
GET /accounts | PSP_AI |
GET /accounts/{accountId}/transactions | PSP_AI |
GET /accounts/{accountId}/transactions/{transactionId} | PSP_AI |
GET /funds-confirmation | PSP_PI |
Error Handling
Each endpoint defines its own set of error responses:
| Endpoint | 400 | 404 | 500 |
|---|---|---|---|
GET /accounts | ✓ | ||
GET /accounts/{accountId}/transactions | ✓ | ||
GET /accounts/{accountId}/transactions/{transactionId} | ✓ | ✓ | ✓ |
GET /funds-confirmation | ✓ | ✓ |
| Status | Description |
|---|---|
400 | Invalid request parameters |
404 | Resource not found |
500 | Internal server error |
Error responses include an errorCode and message for debugging.