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.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.