Getting started
-
Create an account and complete onboarding at app.pmnt.app — add your business entity and its IBAN bank account.
-
Generate an API key under Settings → API keys. The full key is shown only once, right after creation — store it securely.
-
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.GET /delivery-providers,GET /delivery-providers/{id}— the delivery providers dictionary.GET /categories,GET /categories/{id},GET /purposes,GET /purposes/{id}— the payment dictionaries.
Subscription
API access follows the subscription on your account. Once it lapses, the owner endpoints answer 402 Payment Required with the error code subscription_required and a meta object carrying subscribe_url, status, and subscribed_until.
GET /me stays available so a client can always identify itself and read its own status, as do the public endpoints listed above.
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"
}
]
}
| Status | Meaning |
|---|---|
402 |
The subscription on the account has lapsed. See Subscription. |
403 |
No API key, or a key that is not allowed to perform this action. |
404 |
No such record — also what another account's records look like from your key. |
422 |
The request body failed validation; the error objects point at the offending fields. |
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, together with its delivery details, its QR image, and its visit history. See Deleting data.
- 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, its bank accounts, and every invoice issued from it. See Deleting data.
- 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 and every invoice drawn on it. See Deleting data.
- POST
/bank-accounts/{id}/set-primary - Make this account the primary one.
Delivery
Optional delivery-details collection for invoices that require shipping.
- 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.
Deleting data
Deletes are permanent — there is no soft delete and no restore. They also cascade: removing a record removes everything that only exists because of it.
Deleting a business entity takes its bank accounts and every invoice issued from it. Deleting a bank account takes every invoice drawn on it — an invoice is payable only through the account it names, so it cannot outlive it. Deleting an invoice takes its delivery details, its QR image, and its visit history.
The cascade does not spare paid invoices: deleting an entity or an account takes its whole payment history with it. Payer pages (https://app.pmnt.app/pay/{short_code}) of deleted invoices stop resolving immediately.
To take an invoice out of circulation while keeping its record, use POST /invoices/{id}/disable instead — it can be undone with POST /invoices/{id}/enable.
Support
Questions about the API? Write to admin@pmnt.app or browse the Help Center.