API documentation

Issue invoices with NBU payment QR codes, manage business entities and bank accounts, and read payment analytics — the same JSON:API that powers app.pmnt.app.

Getting started

  1. Create an account and complete onboarding at app.pmnt.app — add your business entity and its IBAN bank account.

  2. Generate an API key under Settings → API keys. The full key is shown only once, right after creation — store it securely.

  3. Make your first request:

    curl https://app.pmnt.app/api/me \
    -H "Authorization: Bearer apa_YOUR_API_KEY" \
    -H "Accept: application/vnd.api+json"

Authentication

Every request to a protected endpoint carries your API key in the Authorization header. Keys are opaque strings prefixed with apa_ — they are not JWTs.

Authorization: Bearer apa_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  • A key is bound to your user account and carries its full permissions — there are no per-key scopes yet.
  • Only a hash of the key is stored. If you lose a key, create a new one and revoke the old one — revocation takes effect immediately.
  • Requests without a valid key receive 403 Forbidden on protected endpoints.

API access types

All endpoints require an API key by default — pass it as Authorization: Bearer apa_… with every request. Only a few public endpoints are callable without a key:

  • GET /invoice/{short_code} — public invoice lookup; the short code itself acts as the access token.
  • POST /delivery-info — delivery details submitted by the payer page.
  • GET /delivery-providers, GET /delivery-providers/{id} — the delivery providers dictionary.
  • GET /categories, GET /categories/{id}, GET /purposes, GET /purposes/{id} — the payment dictionaries.

JSON:API conventions

The API follows the JSON:API 1.0 specification. Send and expect the content type application/vnd.api+json. List endpoints support the standard query parameters:

Parameter Description Example
filter[attr] Filter the list by an attribute value. ?filter[state]=paid
sort Comma-separated sort fields; prefix a field with - for descending. ?sort=-qr_generated_at
page[limit] Keyset pagination: page size plus page[after] / page[before] cursors taken from the previous response. ?page[limit]=25
page[count] Include the total record count in the meta object. ?page[count]=true
include Side-load related resources in the same response. ?include=business_entity,bank_account
fields[type] Sparse fieldsets: return only the listed attributes. ?fields[invoice]=short_code,state

Errors

Errors come back as a JSON:API error envelope with an HTTP status that matches the outermost error:

{
"errors": [
{
"status": "403",
"title": "Forbidden",
"detail": "forbidden"
}
]
}

Endpoints

All paths are relative to the base URL. Every endpoint requires an API key unless it is listed under API access types. The generated OpenAPI specification remains the canonical, always-current reference.

Base URL: https://app.pmnt.app/api · Interactive Swagger UI · OpenAPI specification (JSON)

Profile

Identify the account behind an API key.

GET /me
Current user profile for the presented API key.

Invoices

Issue and manage payment invoices. Every invoice gets a public payer page and an NBU payment QR code.

GET /invoices
List your invoices (filterable, paginated).
POST /invoices
Create an invoice. QR code generation is queued automatically.
GET /invoices/{id}
Fetch a single invoice.
PATCH /invoices/{id}
Update the buyer note or the favorite flag.
DELETE /invoices/{id}
Delete an invoice.
POST /invoices/{id}/disable
Disable an active invoice.
POST /invoices/{id}/enable
Re-enable a disabled invoice.
POST /invoices/{id}/confirm-payment
Mark an invoice as paid.
GET /invoice/{short_code}
Public invoice lookup by short code. The short code itself is the access token; owner-only fields stay masked.

For example, create an invoice and receive its payer page and QR code:

curl -X POST https://app.pmnt.app/api/invoices \
-H "Authorization: Bearer apa_YOUR_API_KEY" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{
"data": {
"type": "invoice",
"attributes": {
"business_entity_id": "YOUR_BUSINESS_ENTITY_ID",
"bank_account_id": "YOUR_BANK_ACCOUNT_ID",
"purpose": "Оплата за послуги",
"amount": 1980
}
}
}'

The response arrives with state created; qr_url is filled in asynchronously moments later. The payer page lives at https://app.pmnt.app/pay/{short_code}.

{
"data": {
"type": "invoice",
"id": "6b9f2c1e-4a5d-4e8f-9c3b-2d7a8e1f0b4c",
"attributes": {
"short_code": "…",
"state": "created",
"qr_url": null
}
}
}

Business entities

Companies, private entrepreneurs, and individuals you issue invoices from. Tax numbers (EDRPOU/RNOKPP) are validated automatically.

GET /business-entities
List your business entities.
POST /business-entities
Create a business entity (name, tax number, type).
GET /business-entities/{id}
Fetch a single business entity.
PATCH /business-entities/{id}
Update the name or the type.
DELETE /business-entities/{id}
Delete an entity that has no invoices.
POST /business-entities/{id}/set-default
Make this entity the default one.

Bank accounts

IBAN accounts attached to your business entities. Bank details are resolved from the IBAN automatically.

GET /bank-accounts
List your bank accounts.
POST /bank-accounts
Add an IBAN to a business entity.
GET /bank-accounts/{id}
Fetch a single bank account.
PATCH /bank-accounts/{id}
Update the primary flag.
DELETE /bank-accounts/{id}
Delete a bank account.
POST /bank-accounts/{id}/set-primary
Make this account the primary one.

Delivery

Optional delivery-details collection for invoices that require shipping.

POST /delivery-info
Submit delivery details for an invoice (used by the payer page).
GET /delivery-providers
List supported delivery providers.
GET /delivery-providers/{id}
Fetch a delivery provider.

Dictionaries

Reference data for invoice categorization: NBU payment categories and purposes.

GET /categories
List payment categories.
GET /categories/{id}
Fetch a payment category.
GET /purposes
List payment purposes.
GET /purposes/{id}
Fetch a payment purpose.

Analytics

Visit tracking for invoice payer pages: who opened them, when, and from where.

GET /invoices/{id}/visits
List visits of an invoice page (up to 100 per request).
GET /invoices/{id}/visits/stats
Aggregated visit statistics with an optional from/to range.

Invoice lifecycle

An invoice moves through the following states; transitions happen via the payer page and the endpoints above:

stateDiagram-v2
    direction LR
    [*] --> created: POST /invoices
    created --> pending_delivery: delivery required
    created --> awaiting_payment: payer opens the page
    pending_delivery --> awaiting_payment: delivery submitted
    created --> paid: confirm-payment
    awaiting_payment --> paid: confirm-payment
    created --> expired: valid_until passes
    pending_delivery --> expired
    awaiting_payment --> expired
    created --> disabled: disable
    pending_delivery --> disabled
    awaiting_payment --> disabled
    disabled --> created: enable
  • created — The invoice is issued, but nobody has opened its payer page yet.
  • pending_delivery — The payer opened an invoice that requires delivery and has not submitted delivery details yet.
  • awaiting_payment — The payer opened the payment page.
  • paid — The owner confirmed the payment via confirm-payment.
  • expired — The valid_until deadline has passed; expiry is applied automatically every minute.
  • disabled — Manually disabled via disable; enable returns it to created.

Full attribute schemas and the remaining enums (field_lock_preset, transfer_type, …) are part of the OpenAPI specification.

Support

Questions about the API? Write to admin@pmnt.app or browse the Help Center.