API Documentation
External API documentation for integration with the Karbovanets platform.
Authentication
All API endpoints require authentication using one of the following methods:
API Key (Recommended for integrations)
X-API-Key: krb_aBcDeFgHiJkLmNoPqRsTuVwXyZ123456789012345678
Bearer Token
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Important: The first API key must be created through the web version of your personal account. After that, you can create additional keys via API. Maximum 3 keys per user.
Error Codes
| Code | Description |
|---|---|
| 400 | Bad Request - Invalid input data |
| 401 | Unauthorized - Invalid or missing authentication |
| 404 | Not Found - Resource not found |
| 409 | Conflict - Business logic conflict |
| 422 | Unprocessable Entity - Validation failed |
User Info
Returns information about the authenticated user.
Response
{
"data": {
"type": "users",
"id": "GApnxJlkaIVC92d4o44n6",
"attributes": {
"email": "[email protected]",
"balance": {
"value": "1500.00000000",
"precision": 8
},
"language": "uk",
"created_at": "2024-01-15 10:30:00",
"updated_at": "2024-03-18 14:20:00"
}
}
}
User Language
Persists the language preference of the authenticated user. This value drives the locale of all transactional emails (email verification, order status updates, etc.). Available codes are determined by the active language list on the server (currently: en, uk, ru).
Request body
{
"data": {
"type": "language",
"attributes": {
"code": "uk"
}
}
}
Response
204 No Content on success. 422 Unprocessable Entity if the language code is unknown or the language is inactive.
API Keys
Creates a new API key. Maximum 3 keys per user.
Warning: The key is shown only once upon creation. Save it securely.
Response (201 Created)
{
"data": {
"type": "api_keys",
"id": "xK9mNpQrStUvWxYz12345",
"attributes": {
"key": "krb_aBcDeFgHiJkLmNoPqRsTuVwXyZ123456789012345678",
"callback_signing_key": "aBcD1234eFgH5678iJkL9012mNoP3456qRsT7890uVwX1234yZ56",
"created_at": "2024-03-18T10:00:00Z"
}
}
}
Response Fields
| Field | Description |
|---|---|
key | The API key itself. Sent in the X-API-Key header for any protected request. |
callback_signing_key | Shared secret for verifying outbound payout webhook signatures (HMAC-SHA512 in the PAYLOAD-WITH-SIGNATURE header). |
Favourite Currencies
Returns a list of user's favourite currencies with pagination.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| page | integer | Page number |
| perPage | integer | Results per page |
| filters[code] | string | Filter by currency code |
| filters[base_currency] | string | Filter by base currency |
Adds a currency to favourites. Response: 204 No Content.
Removes a currency from favourites. Response: 204 No Content.
Orders
Returns a list of user's orders with pagination and filtering.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| page | integer | Page number |
| perPage | integer | Results per page |
| filters[hash] | string | Filter by hash |
| filters[status] | string | CREATED, PENDING, PAID, EXPIRED, CANCELLED |
Order Statuses
| Status | Description |
|---|---|
| CREATED | Order created, awaiting payment |
| PENDING | Payment in progress |
| PAID | Order paid and completed |
| EXPIRED | Payment time expired |
| CANCELLED | Order cancelled |
Returns a single order by ID.
Returns a single order by hash.
Creates a new order.
Request Body
{
"data": {
"type": "create_order_request",
"attributes": {
"payout_type": 1,
"to_amount": "1000",
"to_currency": "P24UAH",
"custom_fields": {
"unq_identifier_37": "4149123456789012"
},
"callback_url": "https://your-site.com/webhook/order"
}
}
}
Request Fields
| Field | Type | Description |
|---|---|---|
| payout_type | integer | Payment method (see below) |
| to_amount | string | Amount to receive |
| to_currency | string | Currency code |
| custom_fields | object | Dynamic currency fields |
| callback_url | string | Webhook URL (optional) |
payout_type Options
| Value | Description |
|---|---|
| 1 | Balance — The order amount will be deducted from user's current balance. User must have sufficient funds. |
| 2 |
Crypto payment — The response will include a wallet address (in_requisite field) where the user needs to send crypto to pay for the order.
|
Cancels an order. Response: 204 No Content.
Downloads order history as a CSV file (up to 1000 recent orders).
Deposits
Returns a list of user's deposits with pagination.
Deposit Statuses
| Status | Description |
|---|---|
| CREATED | Deposit created, awaiting transfer |
| IN_PROGRESS | Transfer in progress |
| SUCCESS | Deposit successfully credited |
| FAILED | Crediting failed |
Returns a single deposit by ID.
Creates a new deposit request.
Request Body
{
"data": {
"type": "create_deposit_request",
"attributes": {
"amount": 500.00
}
}
}
How to top up balance: 1) Create a deposit via POST /deposits. 2) Get the USDT TRC20 address from the response. 3) Send USDT to this address. 4) The system will automatically credit the funds to your balance.
Payout (API-source)
X-API-Key only. Bearer tokens are not accepted on this route. The user whose balance is debited is the owner of the API key — user_id is not accepted in the body.
Creates a payout (an api-source order) in the recipient currency. The amount is debited immediately from the API key owner's balance. Field values are passed by tag — tag → custom field mapping is done internally (see Field Tags).
Request Body
{
"data": {
"type": "create_payout_request",
"attributes": {
"to_currency": "P24UAH",
"to_amount": "1500.00",
"fields": {
"card": "4242424242424242",
"fio": "Ivanov Ivan",
"iban": "UA00..."
},
"callback_url": "https://exchanger.example.com/webhook/auto-withdraws-integrations/karbovanets_uah/abc123",
"external_id": "abc123"
}
}
}
Request Fields
| Field | Type | Description |
|---|---|---|
to_currency | string | Recipient currency code (must exist in the system). |
to_amount | string | Amount in the recipient currency (decimal as string). |
fields | object | Map { tag → value }. See tag table below. |
callback_url | string (url) | URL we POST status updates to (terminal statuses only). |
external_id | string | Your payout identifier. Unique per API key — duplicates return 409. |
Field Tags
Keys in fields are tags of custom fields. The service maps a tag to the configured custom field for the currency and runs its validation (type, min/max length, etc). Tags not associated with any field of the currency are ignored; a missing required tag returns 422 with the tag in field.
Approximate names — to be refined.
| Field | Tag | Example |
|---|---|---|
| Card | card | 4242 4242 4242 4242 |
| CVU / CBU (Argentina) | cbu | 0000003100000000000001 |
| IBAN / CLABE | iban | UA00 0000 0000 0000 0000 0000 000 |
| BSB code (Australia) | bsb | 062-001 |
| Pix Key (Brazil) | pix | [email protected] |
| Recipient account number | account | 26000123456789 |
| Bank name | bank | Privatbank |
| Correspondent bank | corr_bank | JPMorgan Chase, SWIFT CHASUS33 |
| Full name | fio | Ivanov Ivan Ivanovych |
| Phone number | phone | +380501234567 |
email | [email protected] | |
| Tax ID | ipn | 1234567890 |
| Recipient country | country | UA |
| Payment purpose | purpose | Service payment |
Response (201 Created)
{
"data": {
"type": "orders",
"id": "<order_uid>",
"attributes": { "status": "PAID", "hash": "...", "...": "..." }
}
}
Errors
| HTTP | Code | Description |
|---|---|---|
| 400 | 6003 | Not enough balance on the API key owner. |
| 409 | 7003 | Payout with this external_id already exists. |
| 422 | 0000 | Validation failed. The field is the offending tag (e.g. card). |
| 401 | 2003 | X-API-Key missing or invalid. |
Outbound Webhook
After payout creation, the order status updates in the background. We POST to your callback_url only on terminal statuses (COMPLETED, ERROR, CANCELLED, DELETED). The body is signed with HMAC-SHA512 over base64(utf8_encode(raw_body)) using your callback_signing_key (returned when the API key was created). The signature is in the PAYLOAD-WITH-SIGNATURE header.
POST {callback_url}
Content-Type: application/json
PAYLOAD-WITH-SIGNATURE: <hmac-sha512>
{
"status": 3,
"card_number": "4242...",
"amount_to_pay": "1500.00",
"amount_paid": "1500.00",
"payment_id": 12345,
"operator_email": null
}
| status | Meaning |
|---|---|
| 3 | Completed |
| 5 | Failed / cancelled / deleted (ERROR / CANCELLED / DELETED) |
Delivery Retries
Any response that isn't 2xx (including 4xx such as 401, 403, 404, 429) as well as connection-level errors (DNS, timeout) are treated as transient. We retry delivery up to 3 times with backoff: 60s → 300s → 300s. This gives you time to fix an allowlist entry, rotate a token, or finish a short release without losing the webhook. If no 2xx is received after all attempts, the failure is logged; we recommend reconciling order status via your own monitoring as a fallback.
Webhooks
When creating an order with callback_url, the system will send a POST request to your URL when the order status changes.
Webhook Payload
{
"order_id": "coY8sOZ6sej4RKvOUvIgq",
"hash": "abc123def456",
"status": "PAID",
"amount": "100.00000000",
"to_amount": "4125.00000000",
"currency_from": "USDTTRC20",
"currency_to": "P24UAH",
"created_at": "2024-03-18T10:00:00+00:00",
"updated_at": "2024-03-18T10:15:00+00:00"
}
Retry Policy: 3 attempts with delays of 1, 5, and 15 minutes.