# Payout OpenBanking PSD2 API

## Authentication

Every endpoint except enrolment requires an OAuth 2.0 access token (JWT) issued by PayoutID to the
TPP's client. Send it in the `Authorization` header:

    Authorization: Bearer <access_token>

The token must be issued to a TPP client registered with Payout and carry the scope required by
the endpoint:

| Scope | Token | Endpoints |
| ----- | ----- | --------- |
| `AISP` | `authorization_code` grant, on behalf of the user | list accounts, account info, list transactions |
| `PIISP` | `authorization_code` grant, on behalf of the user | balance check |
| `PISP` | `client_credentials` grant | standard sba payment, order status |
| `PISPSUBMIT` | `authorization_code` grant against the order OAuth2 endpoint | submit payment |

AIS endpoints only return data for the accounts the user granted to the TPP.

### PISP: Create and submit order flow

To create order, TPP must first get PISP token using client_credentials against normal OAuth2
endpoint. With this access token it is possible to create order using API. After that, TPP need
to request access token using `authorization_code` method to get `PISPSUBMIT` access token for
created order. This request is done against order OAuth2 endpoint, which is the authorization
URL followed by `/{orderId}`.


## Errors

Authentication failures return `401`:

```json
{
  "status": 401,
  "reason": "Unauthorized"
}
```

This covers a missing, invalid or expired token, a token without the required scope or user,
and a token issued to an unknown client.

Other errors use this shape:

```json
{
  "errors": {
    "message": "Resource not found"
  }
}
```

| Status | Message | When |
| ------ | ------- | ---- |
| 400 | `Bad request` | The body is not valid JSON, a required attribute is missing, or the order ID is not a UUID |
| 404 | `Resource not found` | The account or order does not exist, or the account was not granted to the TPP |
| 406 | `Request is not acceptable` | The `Accept` header does not allow JSON |
| 500 | `Internal server error` | Unexpected error |

Enrolment validation errors and refused payment submissions also return `400`, with the bodies
described at those endpoints.


## enrol

`POST https://sandbox.payout.one/api/psd2/v1/enrol`

Enrol new client. This call will return new client credentials, which will be disabled.
Client TPP then will be contacted via first contact email and process will be finished manually.
The request must contain the TPP's PSD2 certificate.

This endpoint does not require an access token.

### Parameters

- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Request body

- `licenseNumber` — string (required) · PSD2 license number of TPP. Each license number can be enrolled only once. · e.g. 12345
- `clientName` — string (required) · Client name of TPP · e.g. Example TPP, s.r.o.
- `logoUri` — string · URL to publicly accessible logo of TPP · e.g. https://tpp.example.com/logo.png
- `scopes` — string[] (required) · List of scopes which TPP will require · e.g. ['AISP']
- `contacts` — string<email>[] (required) · List of emails which can be used to contact TPP, must be at least one · e.g. ['test@example.com']
- `redirectUris` — string<uri>[] (required) · Redirect URL's which TPP will use. Each must be an absolute HTTPS URL without a fragment. · e.g. ['https://tpp.example.com/oauth/callback']
- `certificate` — string (required) · Base64 encoded PSD2 certificate · e.g. MIIDdzCCAl+gAwIBAgIURXhhbXBsZVBTRDJDZXJ0aWZpY2F0ZQ==

### Response 201

- `licenseNumber` — string · e.g. 12345
- `clientId` — string · e.g. a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f90
- `clientSecret` — string · e.g. 0f1e2d3c4b5a69788796a5b4c3d2e1f00f1e2d3c4b5a69788796a5b4c3d2e1f0
- `cleintName` — string · Client name of TPP · e.g. Example TPP, s.r.o.
- `logoUri` — string | null · e.g. https://tpp.example.com/logo.png
- `scopes` — string[] · e.g. ['AISP']
- `contacts` — string[] · e.g. ['test@example.com']
- `redirectsUris` — string[] · Redirect URIs of TPP · e.g. ['https://tpp.example.com/oauth/callback']

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/psd2/v1/enrol' \
  -H "Content-Type: application/json" \
  -d '{
       "licenseNumber": "12345",
       "clientName": "Example TPP, s.r.o.",
       "logoUri": "https://tpp.example.com/logo.png",
       "certificate": "MIIDdzCCAl+gAwIBAgIURXhhbXBsZVBTRDJDZXJ0aWZpY2F0ZQ==",
       "scopes": [
         "AISP"
       ],
       "contacts": [
         "test@example.com"
       ],
       "redirectUris": [
         "https://tpp.example.com/oauth/callback"
       ]
     }'
```


## list accounts

`GET https://sandbox.payout.one/api/psd2/v1/accounts`

List all accounts of current user that the user granted to the TPP.

### Parameters

- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Response 200

- `creationDateTime` — string<date-time> · Date and time in RFC 3339 format when the list was created · e.g. 2026-10-06T08:15:30.123456+00:00
- `accounts` — object[]
  - `identification` — object
    - `identifier` — string · Unique identification · e.g. Q7v_K2mNp4Xs
  - `name` — string · Name of account · e.g. Example Shop, s.r.o.
  - `productName` — string · Name of product which is represented by this account, statically "Payout Account" · e.g. Payout Account
  - `type` — string · Type of account, statically "CACC" · e.g. CACC
  - `baseCurrency` — string · Currency code of account according to ISO 4217 - 3 capital letters, statically "EUR" · e.g. EUR
  - `servicer` — object · Service responsible for this account
    - `financialInstitutionIdentification` — string · Name of service responsible for this account · e.g. Payout, s.r.o.
  - `consent` — string[] · Scopes acquired for this account · e.g. ['AISP']

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/psd2/v1/accounts' \
  -H "Authorization: Bearer $TOKEN"
```


## account info

`POST https://sandbox.payout.one/api/psd2/v1/accounts/information`

Retrieve detailed info about user account

### Parameters

- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Request body

- `identifier` — string (required) · Identificator of account (`identification.identifier` from list accounts) · e.g. Q7v_K2mNp4Xs

### Response 200

- `account` — object
  - `name` — string · Name of account · e.g. Example Shop, s.r.o.
  - `productName` — string · Name of product of which instance is this account · e.g. Payout Account
  - `baseCurrency` — string · Basic currency of this account in ISO 4217 · e.g. EUR
  - `type` — string · ISO 20022 - Cash Account Type Code · e.g. CACC
- `balances` — object[] · One balance per currency
  - `name` — string · Name of account · e.g. Example Shop, s.r.o.
  - `typeCodeOrProprietary` — string · Statically "ITAV" · e.g. ITAV
  - `amount` — object · Represent value with currency
    - `value` — string · Decimal amount of money, serialized as a string · e.g. 3055.8500
    - `currency` — string · Currency code according to ISO 4217 - 3 capital letters · e.g. EUR
  - `creditDebitIndicator` — string · "CRDT" when incoming funds exceed outgoing funds, otherwise "DBIT" · one of CRDT, DBIT · e.g. CRDT
  - `dateTime` — string<date-time> · Date and time in RFC 3339 format when the balance was read · e.g. 2026-10-06T08:15:30.123456+00:00

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/psd2/v1/accounts/information' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "identifier": "Q7v_K2mNp4Xs"
     }'
```


## list transactions

`POST https://sandbox.payout.one/api/psd2/v1/accounts/transactions`

List all transactions for user or account. Only accounts the user granted to the TPP are
included. Transactions are returned newest first.

### Parameters

- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Request body

- `identifier` — string · Identifier of account for which to return transactions · e.g. Q7v_K2mNp4Xs
- `dateFrom` — string<date> · Limit results to be newer than specified date (YYYY-MM-DD) · e.g. 2026-09-01
- `dateTo` — string<date> · Limit results to be older than specified date (YYYY-MM-DD) · e.g. 2026-09-30
- `status` — string · Filter transactions by their state · one of BOOKED, INFO · e.g. BOOKED
- `pageSize` — integer · Number of results to return · e.g. 20
- `page` — integer · Current page in pagination, starting at 0 · e.g. 4

### Response 200

- `pageCount` — integer · Total number of pages after filtering · e.g. 3
- `transactions` — object[] · List of returned transactions
  - `amount` — object · Represent value with currency
    - `value` — string · Decimal amount of money, serialized as a string · e.g. 3055.8500
    - `currency` — string · Currency code according to ISO 4217 - 3 capital letters · e.g. EUR
  - `creditDebitIndicator` — string · Indicates if this transaction is credit or debit transaction · one of CRDT, DBIT · e.g. CRDT
  - `reversalIndicator` — boolean · Indicates if this transaction is rollback of some previous transaction · e.g. False
  - `status` — string · Indicates whatever transaction was executed ("INFO") or is pending ("BOOKED") · one of INFO, BOOKED · e.g. INFO
  - `bookingDate` — string<date> · e.g. 2026-09-15
  - `valueDate` — string<date> · e.g. 2026-09-15
  - `bankTransactionCode` — string · "GHC" for fee transactions, "PM" for all other transactions · one of PM, GHC · e.g. PM
  - `transactionDetails` — object
    - `references` — object · Attribute that identify transaction
      - `accountServicerReference` — string · Internal service provider transaction reference · e.g. 184512
      - `endToEndIdentification` — string | null · Transaction reference in the form `/VS{variable symbol}/SS/KS`, or null when the transaction has none · e.g. /VS20260915/SS/KS
    - `relatedParties` — object · Parties between which transaction is executed
      - `debtor` — object
        - `name` — string · Name of the party · e.g. Example Customer
      - `debtorAccount` — object
        - `identification` — string · Globaly identifies party, can be internal identificator, IBAN, etc. · e.g. CZ6508000000192000145399
      - `creditor` — object
        - `name` — string · Name of the party · e.g. Example Shop, s.r.o.
      - `creditorAccount` — object
        - `identification` — string · Globaly identifies party, can be internal identificator, IBAN, etc. · e.g. Q7v_K2mNp4Xs
    - `relatedDates` — object · Important dates from transaction processing
      - `acceptanceDateTime` — string<date> · e.g. 2026-09-15

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/psd2/v1/accounts/transactions' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "page": 2,
       "identifier": "Q7v_K2mNp4Xs"
     }'
```


## standard sba payment

`POST https://sandbox.payout.one/api/psd2/v1/payments/standard/sba`

Initialize payment using json format. The order is created in status `PDNG` and is executed
only after it is submitted with submit payment.

### Parameters

- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Request body

- `instructionIdentification` — string (required) · Client assigned instruction identification · e.g. aff52ratg5ageh53
- `debtor` — object (required)
  - `identifier` — string (required) · Debtor identifier, the account identifier (`identification.identifier` from list accounts) · e.g. Q7v_K2mNp4Xs
- `creditor` — object (required)
  - `name` — string (required) · Full name or company name of creditor · e.g. Example Supplier, s.r.o.
  - `iban` — string (required) · e.g. SK3112000000198742637541
  - `email` — string (required) · e.g. billing@example.com
- `instructedAmount` — object (required)
  - `value` — number (required) · Number with two decimals representing money amount · e.g. 12.5
  - `currency` — string (required) · Currency code according to ISO 4217 · e.g. EUR
- `endToEndIdentification` — string · Client assigned transaction reference. In the form `/VS{variable symbol}/SS{specific symbol}/KS{constant symbol}` the variable symbol becomes the payment reference; it must be numeric with at most 10 digits, otherwise the submission is refused. · e.g. /VS20261006/SS/KS
- `remittanceInformation` — string · e.g. Invoice 2026-104

### Response 201

- `orderId` — string<uuid> · e.g. 3b0f6c2e-8d41-4a7b-9c55-1e2f3a4b5c6d
- `status` — string · "PDNG" - created, not submitted yet; "ACSC" - submitted, payment created; "RJCT" - submission refused (returned only by submit payment) · one of PDNG, ACSC, RJCT · e.g. PDNG
- `statusDatetime` — string<date-time> · Date and time when status was read · e.g. 2026-10-06T08:15:30.123456Z

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/psd2/v1/payments/standard/sba' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "instructionIdentification": "aff52ratg5ageh53",
       "debtor": {
         "identifier": "Q7v_K2mNp4Xs"
       },
       "creditor": {
         "name": "Example Supplier, s.r.o.",
         "iban": "SK3112000000198742637541",
         "email": "billing@example.com"
       },
       "instructedAmount": {
         "value": 12.5,
         "currency": "EUR"
       },
       "endToEndIdentification": "/VS20261006/SS/KS",
       "remittanceInformation": "Invoice 2026-104"
     }'
```


## submit payment

`POST https://sandbox.payout.one/api/psd2/v1/payments/submission`

Submit initialized payment for processing. This request is done only with access token that
can be retrieved using `authorization_code` oauth2 method against the order OAuth2 endpoint
(the authorization URL followed by `/{orderId}`) and requires scope `PISPSUBMIT`.

The order is identified by the access token; the request has no body. Submitting an order
that was already submitted returns it unchanged with `200`.

### Parameters

- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Response 201

- `orderId` — string<uuid> · e.g. 3b0f6c2e-8d41-4a7b-9c55-1e2f3a4b5c6d
- `status` — string · "PDNG" - created, not submitted yet; "ACSC" - submitted, payment created; "RJCT" - submission refused (returned only by submit payment) · one of PDNG, ACSC, RJCT · e.g. PDNG
- `statusDatetime` — string<date-time> · Date and time when status was read · e.g. 2026-10-06T08:15:30.123456Z

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/psd2/v1/payments/submission' \
  -H "Authorization: Bearer $TOKEN"
```


## order status

`GET https://sandbox.payout.one/api/psd2/v1/payments/{order_id}/status`

Return actual status of the order

### Parameters

- `order_id` (path, required) — Order ID returned as `orderId` by standard sba payment
- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Response 200

- `orderId` — string<uuid> · e.g. 3b0f6c2e-8d41-4a7b-9c55-1e2f3a4b5c6d
- `status` — string · "PDNG" - created, not submitted yet; "ACSC" - submitted, payment created; "RJCT" - submission refused (returned only by submit payment) · one of PDNG, ACSC, RJCT · e.g. PDNG
- `statusDatetime` — string<date-time> · Date and time when status was read · e.g. 2026-10-06T08:15:30.123456Z

### Example

```bash
curl -X GET 'https://sandbox.payout.one/api/psd2/v1/payments/{order_id}/status' \
  -H "Authorization: Bearer $TOKEN"
```


## balance check

`POST https://sandbox.payout.one/api/psd2/v1/accounts/balanceCheck`

Check if account has enough resources to fulfill specified request. The response is `APPR`
when the available balance in the requested currency is greater than `amount`, otherwise
`DECL`.

### Parameters

- `Correlation-ID` (header) — Match request to response. Echoed back in the `correlation-id` response header.
- `Process-ID` (header) — Group multiple Request-Response pairs to single process. Echoed back in the `process-id` response header.

### Request body

- `instructionIdentification` — string · Technical payment identificator generated by PIISP. Accepted but not evaluated. · e.g. piisp-20261006-0001
- `creationDateTime` — string<date-time> · The date and time in RFC3339 format at which a particular action has been requested or executed. Accepted but not evaluated. · e.g. 2026-10-06T08:15:30+00:00
- `identifier` — string (required) · Payout account unique identificator · e.g. Q7v_K2mNp4Xs
- `amount` — object (required)
  - `amount` — integer | string (required) · Numeric value of the amount, as an integer or a decimal string such as "60.50". Fractional JSON numbers are not accepted. · e.g. 6000
  - `currency` — string (required) · Alphabetic codes from ISO 4217. · e.g. EUR

### Response 200

- `response` — string · Either "APPR" or "DECL" · one of APPR, DECL · e.g. APPR
- `dateTime` — string<date-time> · The date and time in RFC3339 format at which a particular action has been requested or executed. · e.g. 2026-10-06T08:15:30.123456+00:00

### Example

```bash
curl -X POST 'https://sandbox.payout.one/api/psd2/v1/accounts/balanceCheck' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "instructionIdentification": "piisp-20261006-0001",
       "identifier": "Q7v_K2mNp4Xs",
       "amount": {
         "amount": 6000,
         "currency": "EUR"
       }
     }'
```

