IntegrateAPI reference
Integrate

API reference

Every merchant endpoint, request field, response and webhook payload, generated from openapi.yaml.

Markdown

This page is generated from openapi.yaml in the repository. The file is an OpenAPI 3.1 document. Load it into your own tools to generate a client or to test requests.

The base URL is your site URL, for example https://pay.example.com. Send the project API key in the x-api-key header. Payout endpoints also need a JWT from POST /v1/auth in the Authorization: Bearer header. The Merchant API guide explains each flow with examples.

Payments

Create payments and read their status.

GET/v1/payment

List payments

Auth: apiKey

Parameters

limitquery
integerPayments per page. Turmite changes a value below 1 to 1 and a value above 500 to 500.
pagequery
integerPage number. The first page is 0.
sortByquery
stringpayment_idpayment_statuspay_addressprice_amountprice_currencypay_amountactually_paidpay_currencyorder_idorder_descriptionpurchase_idoutcome_amountoutcome_currencycreated_atupdated_at
orderByquery
stringascdesc
dateFromquery
stringEarliest `created_at`. A date or a date-time.
dateToquery
stringLatest `created_at`. A date or a date-time.
invoiceIdquery
integer (int64)Only the payments of this invoice.
payment_statusquery
stringOnly the payments with this status.waitingconfirmingconfirmedsendingpartially_paidfinishedfailedrefundedexpired
order_idquery
stringOnly the payments with this `order_id`.
200One page of payments.
{
  "data": [
    {
      "invoice_id": 0,
      "payment_status": "waiting",
      "pay_address": "string",
      "payin_extra_id": "string",
      "price_amount": 0,
      "price_currency": "usd",
      "pay_amount": 0,
      "actually_paid": 0,
      "pay_currency": "btc",
      "order_id": "string",
      "order_description": "string",
      "outcome_amount": 0,
      "outcome_currency": "string",
      "network": "btc",
      "network_precision": 0,
      "smart_contract": "string",
      "payin_hash": "string",
      "payout_hash": "string",
      "payment_url": "string",
      "created_at": "2026-10-23T12:00:00Z",
      "updated_at": "2026-10-23T12:00:00Z",
      "expiration_estimate_date": "2026-10-23T12:00:00Z",
      "parent_payment_id": null,
      "type": "crypto2crypto",
      "time_limit": null,
      "burning_percent": null,
      "payment_extra_ids": null,
      "amount_received": 0,
      "actually_paid_at_fiat": 0,
      "fee": {
        "currency": "btc",
        "depositFee": 0,
        "withdrawalFee": 0,
        "serviceFee": 0
      },
      "payment_id": 0,
      "purchase_id": 6084815412
    }
  ],
  "limit": 0,
  "page": 0,
  "pagesCount": 0,
  "total": 0
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

POST/v1/payment

Create a payment

Reserves a deposit address and fixes the amount to pay in `pay_currency`. Send the customer to your own page with `pay_address` and `pay_amount`, or use an invoice for the hosted checkout. A retry with the same `idempotency_key` returns the first payment. In this response `payment_id` and `purchase_id` are strings.

Auth: apiKey

Parameters

Idempotency-Keyheader
stringThe same as `idempotency_key` in the body. The body field has priority.

Body

price_amountrequired
number | stringA positive amount, as a JSON number or a decimal string.
price_currencyrequired
stringA fiat code or a ticker.
pay_currencyrequired
stringThe ticker the customer pays with.
pay_amount
number | stringA fixed amount in `pay_currency`. Without it, Turmite converts `price_amount` at the current rate.
order_id
stringYour order reference. Webhooks include it.
order_description
string
ipn_callback_url
string (uri)Turmite sends payment webhooks to this URL. On mainnet it must be a public `https` URL.
success_url
string (uri)Where the checkout sends the customer after payment.
cancel_url
string (uri)
purchase_id
stringYour id for the purchase. Without it, Turmite makes numeric text.
idempotency_key
stringA request with a key that the project used before returns the first payment. This is also true for two requests at the same time. Turmite does not compare the other fields.

Request body

{
  "price_amount": 100,
  "price_currency": "usd",
  "pay_currency": "btc",
  "order_id": "1042",
  "order_description": "Order #1042",
  "ipn_callback_url": "https://shop.example.com/turmite/ipn",
  "idempotency_key": "order-1042"
}
201The new payment.
{
  "payment_id": "5077125051",
  "invoice_id": null,
  "payment_status": "waiting",
  "pay_address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
  "payin_extra_id": null,
  "price_amount": 100,
  "price_currency": "usd",
  "pay_amount": 0.00123,
  "actually_paid": 0,
  "pay_currency": "btc",
  "order_id": "1042",
  "order_description": "Order #1042",
  "purchase_id": "6084815412",
  "outcome_amount": null,
  "outcome_currency": "btc",
  "network": "btc",
  "network_precision": 8,
  "smart_contract": null,
  "payin_hash": null,
  "payout_hash": null,
  "payment_url": "https://pay.example.com/pay/Q7mX2pK9vT4nB8cR1sW6yZ3h",
  "created_at": "2026-10-23T12:00:00.000Z",
  "updated_at": "2026-10-23T12:00:00.000Z",
  "expiration_estimate_date": "2026-10-23T12:15:00.000Z",
  "parent_payment_id": null,
  "type": "crypto2crypto",
  "time_limit": null,
  "burning_percent": null,
  "payment_extra_ids": null,
  "amount_received": 0.00123,
  "actually_paid_at_fiat": 0,
  "fee": {
    "currency": "btc",
    "depositFee": 0,
    "withdrawalFee": 0,
    "serviceFee": 0
  }
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}
503A service that the request needs is not available, for example the exchange rates. Try again later.
{
  "status": false,
  "statusCode": 503,
  "code": "UNAVAILABLE",
  "message": "Exchange rates are not available. Try again in a minute."
}

GET/v1/payment/{payment_id}

Get a payment

Ship the order only when `payment_status` is `finished`. Use webhooks instead of frequent polls.

Auth: apiKey

Parameters

payment_idpathrequired
integer (int64)
200The payment.
{
  "payment_id": 5077125051,
  "invoice_id": 4522625843,
  "payment_status": "finished",
  "pay_address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
  "payin_extra_id": null,
  "price_amount": 100,
  "price_currency": "usd",
  "pay_amount": 0.00123,
  "actually_paid": 0.00123,
  "pay_currency": "btc",
  "order_id": "1042",
  "order_description": "Order #1042",
  "purchase_id": 6084815412,
  "outcome_amount": 0.00123,
  "outcome_currency": "btc",
  "network": "btc",
  "network_precision": 8,
  "smart_contract": null,
  "payin_hash": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  "payout_hash": null,
  "payment_url": "https://pay.example.com/pay/Q7mX2pK9vT4nB8cR1sW6yZ3h",
  "created_at": "2026-10-23T12:00:00.000Z",
  "updated_at": "2026-10-23T12:14:03.512Z",
  "expiration_estimate_date": "2026-10-23T12:15:00.000Z",
  "parent_payment_id": null,
  "type": "crypto2crypto",
  "time_limit": null,
  "burning_percent": null,
  "payment_extra_ids": null,
  "amount_received": 0.00123,
  "actually_paid_at_fiat": 100,
  "fee": {
    "currency": "btc",
    "depositFee": 0,
    "withdrawalFee": 0,
    "serviceFee": 0
  }
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
404Not found, or it belongs to another project.
{
  "status": false,
  "statusCode": 404,
  "code": "NOT_FOUND",
  "message": "not found"
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

Invoices

Hosted invoices. The customer selects the coin on the invoice page.

POST/v1/invoice

Create an invoice

Returns `invoice_url`, a hosted checkout page. Send the customer there. The customer selects a coin, and Turmite creates a payment for the invoice. The payment copies `order_id`, `order_description`, `ipn_callback_url`, `success_url` and `cancel_url` from the invoice. Webhooks for that payment go to the invoice's `ipn_callback_url`.

Auth: apiKey

Body

price_amountrequired
number | stringA positive amount, as a JSON number or a decimal string.
price_currencyrequired
string
pay_currency
stringSet it to skip the coin selection on the invoice page.
order_id
string
order_description
string
ipn_callback_url
string (uri)Turmite sends the webhooks of the invoice's payments to this URL.
success_url
string (uri)
cancel_url
string (uri)

Request body

{
  "price_amount": 49.9,
  "price_currency": "eur",
  "order_id": "1042",
  "order_description": "Order #1042",
  "ipn_callback_url": "https://shop.example.com/turmite/ipn",
  "success_url": "https://shop.example.com/checkout/order-received/1042",
  "cancel_url": "https://shop.example.com/checkout"
}
201The new invoice.
{
  "id": "4522625843",
  "token_id": "k3J9xQ2vT8mZ5wR1nB7cY4pL",
  "order_id": "1042",
  "order_description": "Order #1042",
  "price_amount": "49.9",
  "price_currency": "eur",
  "pay_currency": null,
  "ipn_callback_url": "https://shop.example.com/turmite/ipn",
  "invoice_url": "https://pay.example.com/i/k3J9xQ2vT8mZ5wR1nB7cY4pL",
  "success_url": "https://shop.example.com/checkout/order-received/1042",
  "cancel_url": "https://shop.example.com/checkout",
  "created_at": "2026-10-23T12:00:00.000Z",
  "updated_at": "2026-10-23T12:00:00.000Z",
  "expiration_estimate_date": "2026-10-23T13:00:00.000Z"
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

POST/v1/invoice-payment

Create a payment for an invoice

Use this to build your own coin selection for an invoice. The payment gets the invoice's price, order and URLs. If the invoice has an open payment in `pay_currency`, Turmite returns that payment. In this response `payment_id` and `purchase_id` are strings.

Auth: apiKey

Body

iidrequired
integer (int64) | stringThe invoice `id`.
pay_currencyrequired
string
purchase_id
string

Request body

{
  "iid": "4522625843",
  "pay_currency": "usdttrc20"
}
201The new payment.
{
  "payment_id": "5077125051",
  "invoice_id": null,
  "payment_status": "waiting",
  "pay_address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
  "payin_extra_id": null,
  "price_amount": 100,
  "price_currency": "usd",
  "pay_amount": 0.00123,
  "actually_paid": 0,
  "pay_currency": "btc",
  "order_id": "1042",
  "order_description": "Order #1042",
  "purchase_id": "6084815412",
  "outcome_amount": null,
  "outcome_currency": "btc",
  "network": "btc",
  "network_precision": 8,
  "smart_contract": null,
  "payin_hash": null,
  "payout_hash": null,
  "payment_url": "https://pay.example.com/pay/Q7mX2pK9vT4nB8cR1sW6yZ3h",
  "created_at": "2026-10-23T12:00:00.000Z",
  "updated_at": "2026-10-23T12:00:00.000Z",
  "expiration_estimate_date": "2026-10-23T12:15:00.000Z",
  "parent_payment_id": null,
  "type": "crypto2crypto",
  "time_limit": null,
  "burning_percent": null,
  "payment_extra_ids": null,
  "amount_received": 0.00123,
  "actually_paid_at_fiat": 0,
  "fee": {
    "currency": "btc",
    "depositFee": 0,
    "withdrawalFee": 0,
    "serviceFee": 0
  }
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
404Not found, or it belongs to another project.
{
  "status": false,
  "statusCode": 404,
  "code": "NOT_FOUND",
  "message": "not found"
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}
503A service that the request needs is not available, for example the exchange rates. Try again later.
{
  "status": false,
  "statusCode": 503,
  "code": "UNAVAILABLE",
  "message": "Exchange rates are not available. Try again in a minute."
}

Payouts

Send funds from the project's hot wallets.

GET/v1/payout

List payouts

Auth: apiKey, bearerAuth

Parameters

batch_idquery
stringOnly the payouts of this batch.
statusquery
stringOnly the payouts with this status. An unknown status returns `400`.pending-approvalpending-otp-verificationpendingsigninginitiatedsentfailedrejectedcancelledneeds-review
date_fromquery
stringEarliest `created_at`. A date or a date-time.
date_toquery
stringLatest `created_at`. A date or a date-time.
orderquery
stringascdesc
limitquery
integerPayouts per page. Turmite changes a value below 1 to 1 and a value above 500 to 500.
pagequery
integerPage number. The first page is 0.
200One page of payouts.
{
  "payouts": [
    {
      "id": "string",
      "batch_withdrawal_id": "string",
      "address": "string",
      "extra_id": "string",
      "currency": "string",
      "network": "string",
      "amount": "250",
      "fee": "string",
      "fee_currency": "string",
      "status": "pending-approval",
      "hash": "string",
      "error": "string",
      "ipn_callback_url": "string",
      "payout_description": "string",
      "unique_external_id": "string",
      "created_at": "2026-10-23T12:00:00Z",
      "requested_at": "2026-10-23T12:00:00Z",
      "updated_at": "2026-10-23T12:00:00Z"
    }
  ],
  "limit": 0,
  "page": 0,
  "pagesCount": 0,
  "total": 0
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
403The key or the user cannot do this action.
{
  "status": false,
  "statusCode": 403,
  "code": "FORBIDDEN",
  "message": "Only a project admin can create or verify payouts."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

POST/v1/payout

Create a payout batch

Creates one payout per withdrawal. The bearer token must belong to a project admin of the API key's project. Each address must be in the project's address book. New payouts are `pending-otp-verification` until you verify the batch with `POST /v1/payout/{batch_id}/verify`. A withdrawal with a `unique_external_id` that already exists returns the existing payout. The same id with other fields returns `409`. At most 100 withdrawals per batch. Bitcoin and Monero have no payouts.

Auth: apiKey, bearerAuth

Body

withdrawalsrequired
object[]
withdrawals[].addressrequired
stringThe destination. It must be in the project's address book.
withdrawals[].currencyrequired
string
withdrawals[].amountrequired
number | stringA positive amount, as a JSON number or a decimal string.
withdrawals[].extra_id
stringThe memo or tag of the destination.
withdrawals[].ipn_callback_url
string (uri)Turmite sends payout webhooks to this URL. Without it, the batch's `ipn_callback_url` is used.
withdrawals[].payout_description
string
withdrawals[].unique_external_id
stringYour id for this payout. A second request with the same id and fields returns the existing payout. The same id with other fields returns `409`.
ipn_callback_url
string (uri)Payout webhooks for each withdrawal without its own `ipn_callback_url`.

Request body

{
  "withdrawals": [
    {
      "address": "TQrZ9wBzhXnHdAdKwRBfdMH2RiTjH6yGtW",
      "currency": "usdttrc20",
      "amount": "250.00",
      "ipn_callback_url": "https://shop.example.com/turmite/payout-ipn",
      "unique_external_id": "refund-1042"
    }
  ]
}
201The new batch.
{
  "id": "5000000713",
  "withdrawals": [
    {
      "id": "5000248325",
      "batch_withdrawal_id": "5000000713",
      "address": "TQrZ9wBzhXnHdAdKwRBfdMH2RiTjH6yGtW",
      "extra_id": null,
      "currency": "usdttrc20",
      "network": "tron",
      "amount": "250",
      "fee": null,
      "fee_currency": "trx",
      "status": "pending-otp-verification",
      "hash": null,
      "error": null,
      "ipn_callback_url": "https://shop.example.com/turmite/payout-ipn",
      "payout_description": null,
      "unique_external_id": "refund-1042",
      "created_at": "2026-10-23T13:00:00.000Z",
      "requested_at": null,
      "updated_at": "2026-10-23T13:00:00.000Z"
    }
  ]
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
403The key or the user cannot do this action.
{
  "status": false,
  "statusCode": 403,
  "code": "FORBIDDEN",
  "message": "Only a project admin can create or verify payouts."
}
409The request conflicts with an existing object.
{
  "status": false,
  "statusCode": 409,
  "code": "CONFLICT",
  "message": "`unique_external_id` is used with other fields."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

POST/v1/payout/{batch_id}/verify

Verify a payout batch

Send the current TOTP code of the user who got the bearer token. That user must be a project admin. Each payout of the batch that waits for verification then goes through the project limits: within them it is `pending`; above the auto-approve amount or the hourly or daily limit it is `pending-approval` until an admin approves it in the dashboard. A wrong code returns `400`. After 5 wrong codes the user is locked for 15 minutes and gets `429`. A user without two-factor authentication gets `403`.

Auth: apiKey, bearerAuth

Parameters

batch_idpathrequired
stringThe `id` of the payout batch.

Body

verification_coderequired
stringThe current TOTP code of the dashboard user.

Request body

{
  "verification_code": "123456"
}
200The batch after verification.
{
  "id": "string",
  "withdrawals": [
    {
      "id": "string",
      "batch_withdrawal_id": "string",
      "address": "string",
      "extra_id": "string",
      "currency": "string",
      "network": "string",
      "amount": "250",
      "fee": "string",
      "fee_currency": "string",
      "status": "pending-approval",
      "hash": "string",
      "error": "string",
      "ipn_callback_url": "string",
      "payout_description": "string",
      "unique_external_id": "string",
      "created_at": "2026-10-23T12:00:00Z",
      "requested_at": "2026-10-23T12:00:00Z",
      "updated_at": "2026-10-23T12:00:00Z"
    }
  ]
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
403The key or the user cannot do this action.
{
  "status": false,
  "statusCode": 403,
  "code": "FORBIDDEN",
  "message": "Only a project admin can create or verify payouts."
}
404Not found, or it belongs to another project.
{
  "status": false,
  "statusCode": 404,
  "code": "NOT_FOUND",
  "message": "not found"
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

GET/v1/payout/{batch_id}

Get a payout batch

Auth: apiKey

Parameters

batch_idpathrequired
stringThe `id` of the payout batch.
200The batch.
{
  "id": "5000000713",
  "withdrawals": [
    {
      "id": "5000248325",
      "batch_withdrawal_id": "5000000713",
      "address": "TQrZ9wBzhXnHdAdKwRBfdMH2RiTjH6yGtW",
      "extra_id": null,
      "currency": "usdttrc20",
      "network": "tron",
      "amount": "250",
      "fee": null,
      "fee_currency": "trx",
      "status": "pending-otp-verification",
      "hash": null,
      "error": null,
      "ipn_callback_url": "https://shop.example.com/turmite/payout-ipn",
      "payout_description": null,
      "unique_external_id": "refund-1042",
      "created_at": "2026-10-23T13:00:00.000Z",
      "requested_at": null,
      "updated_at": "2026-10-23T13:00:00.000Z"
    }
  ]
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
404Not found, or it belongs to another project.
{
  "status": false,
  "statusCode": 404,
  "code": "NOT_FOUND",
  "message": "not found"
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

POST/v1/payout/validate-address

Validate a payout address

Auth: apiKey

Body

addressrequired
string
currencyrequired
string

Request body

{
  "address": "TQrZ9wBzhXnHdAdKwRBfdMH2RiTjH6yGtW",
  "currency": "usdttrc20"
}
200The address is valid. The body is the JSON string `"OK"`. An invalid address or an unknown currency returns `400`.
"OK"
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

GET/v1/payout/fee

Estimate the network fee of a payout

The fee is an estimate from the chain. Turmite measures the real fee when it sends the payout. The hot wallet pays the fee in the native coin of the network (`network_fee` in `fee_currency`); the recipient gets the full amount. `fee` is that cost in `currency`. A Solana token payout to a wallet without a token account also pays the rent of that account.

Auth: apiKey

Parameters

currencyqueryrequired
string
amountquery
string
200The estimated fee in `currency`.
{
  "currency": "usdttrc20",
  "amount": "250",
  "fee": 1.1,
  "network_fee": 4.4,
  "fee_currency": "trx"
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}
503A service that the request needs is not available, for example the exchange rates. Try again later.
{
  "status": false,
  "statusCode": 503,
  "code": "UNAVAILABLE",
  "message": "Exchange rates are not available. Try again in a minute."
}

Reference

Currencies, minimum amounts, estimates and balances.

GET/v1/status

Check that the API is up

200The API is up.
{
  "message": "OK"
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

GET/v1/currencies

List enabled tickers

With a key, the tickers enabled for the key's project. Without a key, the tickers that at least one project takes.

Auth: apiKey

200Enabled tickers.
{
  "currencies": [
    "btc",
    "eth",
    "usdttrc20",
    "sol"
  ]
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

GET/v1/full-currencies

List currencies with details

One entry for each ticker that the server has turned on. `enable` tells if the project takes it.

Auth: apiKey

200One entry per ticker.
{
  "currencies": [
    {
      "id": 7,
      "code": "USDTTRC20",
      "name": "Tether USD",
      "enable": true,
      "wallet_regex": null,
      "priority": 7,
      "extra_id_exists": false,
      "extra_id_regex": null,
      "logo_url": null,
      "track": false,
      "cg_id": "tether",
      "is_maxlimit": false,
      "network": "tron",
      "smart_contract": "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
      "network_precision": "6",
      "ticker": "usdttrc20"
    }
  ]
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

GET/v1/merchant/coins

List the tickers enabled for the project

Auth: apiKey

200Tickers enabled for the key's project.
{
  "selectedCurrencies": [
    "btc",
    "usdttrc20"
  ]
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

GET/v1/min-amount

Get the minimum payment amount

No API key is necessary. Turmite ignores a key that you send.

Parameters

currency_fromqueryrequired
stringThe ticker the customer pays with.
currency_toquery
stringTurmite does not convert. It copies this value to the response. The default is `currency_from`.
fiat_equivalentquery
stringA fiat code. When set and a rate is available, the response has `fiat_equivalent`.
200The minimum payment amount in `currency_from`.
{
  "currency_from": "btc",
  "currency_to": "btc",
  "min_amount": 0.00001,
  "fiat_equivalent": 1.07
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

GET/v1/estimate

Estimate a price in a coin

No API key is necessary. Turmite ignores a key that you send.

Parameters

amountqueryrequired
stringThe amount in `currency_from`.
currency_fromqueryrequired
stringThe price currency, such as `usd`.
currency_toqueryrequired
stringThe ticker the customer pays with.
200The estimate at the current rate.
{
  "currency_from": "usd",
  "amount_from": 100,
  "currency_to": "btc",
  "estimated_amount": "0.00107"
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}
503A service that the request needs is not available, for example the exchange rates. Try again later.
{
  "status": false,
  "statusCode": 503,
  "code": "UNAVAILABLE",
  "message": "Exchange rates are not available. Try again in a minute."
}

GET/v1/balance

Get the project balance per ticker

Auth: apiKey

200One entry per ticker.
{
  "btc": {
    "amount": 0.0153,
    "pendingAmount": 0.0012
  },
  "usdttrc20": {
    "amount": 1250.5,
    "pendingAmount": 0
  }
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

Auth

Bearer tokens for the payout endpoints.

POST/v1/auth

Get a bearer token for the payout endpoints

Use the email and password of a dashboard user. The token is valid for 5 minutes.

Body

emailrequired
string (email)
passwordrequired
string (password)

Request body

{
  "email": "[email protected]",
  "password": "correct-horse-battery-staple"
}
200The token.
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxIn0.c2lnbmF0dXJl"
}
400The request is not valid.
{
  "status": false,
  "statusCode": 400,
  "code": "INVALID_REQUEST_PARAMS",
  "message": "`price_amount` must be greater than 0."
}
401The API key or the bearer token is missing or not valid.
{
  "status": false,
  "statusCode": 401,
  "code": "AUTH_REQUIRED",
  "message": "Invalid API key."
}
429Too many requests.
{
  "status": false,
  "statusCode": 429,
  "code": "TOO_MANY_REQUESTS",
  "message": "too many requests, try again later"
}
500The server failed. The message has no details.
{
  "status": false,
  "statusCode": 500,
  "code": "INTERNAL_ERROR",
  "message": "Internal error."
}

Webhooks

POSTpayment

A payment changed

Turmite sends the payment object to the `ipn_callback_url` of the payment, or of its invoice. It sends one on each status change, one for each new confirmation count while the payment is `confirming`, and one on each extra credit after `finished`. Ship the order only on `finished`. In this body `payment_id` is a number and `purchase_id` is a string. Check the signature before you use the body. The signature header (default `x-turmite-sig`) holds the hex HMAC-SHA512 of the key-sorted JSON body. The key is the project IPN secret. To get the key-sorted JSON from the raw body: 1. Sort the members of each object by key. Compare keys as UTF-8 bytes. Keep the order of arrays. 2. Write compact JSON with no whitespace. 3. Copy each number exactly as it is in the raw body, for example `0.5` or `1e-6`. 4. In strings, escape only `"`, `\` and control characters. Do not escape `/` or non-ASCII characters. `x-turmite-signature` holds `v1=` and the hex HMAC-SHA256 of `<x-turmite-timestamp>.<raw body>`, with the same secret. Refuse a timestamp more than 5 minutes from your clock. Use `x-turmite-delivery` to ignore a delivery that you already processed. A 2xx response acknowledges the delivery. Progress events get 3 attempts: now, after 10 s and after 60 s. Final events get attempts now and after 10 s, 1 m, 5 m, 30 m, 1 h, 2 h, 4 h, 8 h, 24 h and 48 h. Then the delivery is dead. You can retry it from the dashboard.

Parameters

x-turmite-sigheaderrequired
stringHex HMAC-SHA512 of the key-sorted JSON body. The key is the project IPN secret for an `ipn_callback_url`, or the endpoint secret for a project endpoint. The header name is a project setting. The default is `x-turmite-sig`.
x-turmite-timestampheaderrequired
stringUnix time in seconds when Turmite signed this attempt.
x-turmite-signatureheaderrequired
string`v1=` and the hex HMAC-SHA256 of `<x-turmite-timestamp>.<raw body>`. The key is the same as for the signature header.
x-turmite-eventheaderrequired
stringThe event name, such as `payment.finished`, `payout.sent` or `test`.
x-turmite-deliveryheaderrequired
stringThe delivery id. Retries of a delivery use the same id. Use it to ignore duplicates.
user-agentheaderrequired
string

Body

invoice_idrequired
integer (int64) | null
payment_statusrequired
string`waiting`: no deposit yet. `confirming`: a deposit is on the chain with too few confirmations. `confirmed`: the deposit has enough confirmations. `sending`: Turmite moves the funds to the wallet of the project. `partially_paid`: the customer sent less than `pay_amount`. `finished`: paid in full. Ship the order now. `failed`, `refunded` and `expired` are final.waitingconfirmingconfirmedsendingpartially_paidfinishedfailedrefundedexpired
pay_addressrequired
stringThe deposit address.
payin_extra_idrequired
string | nullThe memo or tag the customer must add, on networks that use one.
price_amountrequired
numberThe price in `price_currency`.
price_currencyrequired
stringLowercase.
pay_amountrequired
numberThe amount to pay in `pay_currency`.
actually_paidrequired
numberThe amount received so far.
pay_currencyrequired
string
order_idrequired
string | null
order_descriptionrequired
string | null
outcome_amountrequired
number | nullThe amount credited to the project after network fees.
outcome_currencyrequired
string
networkrequired
stringThe network code. One of `btc`, `xmr`, `eth`, `base`, `polygon`, `bsc`, `tron`, `sol`, `ton`.
network_precisionrequired
integerThe decimals of `pay_currency`.
smart_contractrequired
string | nullThe token contract. Null for a native coin.
payin_hashrequired
string | nullThe transaction hash of the latest deposit.
payout_hashrequired
string | nullThe transaction hash of the latest transfer from the deposit address to the project wallet.
payment_urlrequired
string (uri)The hosted payment page, `<site URL>/pay/<token>`. The token is random.
created_atrequired
string (date-time)
updated_atrequired
string (date-time)
expiration_estimate_daterequired
string (date-time)When the payment expires if no deposit comes.
parent_payment_idrequired
nullAlways null.
typerequired
stringAlways `crypto2crypto`.crypto2crypto
time_limitrequired
nullAlways null.
burning_percentrequired
nullAlways null.
payment_extra_idsrequired
nullAlways null.
amount_receivedrequired
numberThe amount the project gets in `outcome_currency`. `outcome_amount` once funds are credited, else `pay_amount`.
actually_paid_at_fiatrequired
number`actually_paid` in `price_currency`, at the rate of the payment. A payment with a fixed `pay_amount` uses `price_amount / pay_amount` as the rate.
feerequired
objectTurmite takes no fee. `withdrawalFee` is the network fee of the sweeps to the project wallet.
fee.currencyrequired
stringThe same as `pay_currency`.
fee.depositFeerequired
numberAlways 0.
fee.withdrawalFeerequired
number
fee.serviceFeerequired
numberAlways 0.
payment_idrequired
integer (int64)
purchase_idrequired
stringThe `purchase_id` of the request, or numeric text that Turmite makes.

Request body

{
  "payment_id": 5077125051,
  "invoice_id": 4522625843,
  "payment_status": "finished",
  "pay_address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
  "payin_extra_id": null,
  "price_amount": 100,
  "price_currency": "usd",
  "pay_amount": 0.00123,
  "actually_paid": 0.00123,
  "pay_currency": "btc",
  "order_id": "1042",
  "order_description": "Order #1042",
  "purchase_id": "6084815412",
  "outcome_amount": 0.00123,
  "outcome_currency": "btc",
  "network": "btc",
  "network_precision": 8,
  "smart_contract": null,
  "payin_hash": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
  "payout_hash": null,
  "payment_url": "https://pay.example.com/pay/Q7mX2pK9vT4nB8cR1sW6yZ3h",
  "created_at": "2026-10-23T12:00:00.000Z",
  "updated_at": "2026-10-23T12:14:03.512Z",
  "expiration_estimate_date": "2026-10-23T12:15:00.000Z",
  "parent_payment_id": null,
  "type": "crypto2crypto",
  "time_limit": null,
  "burning_percent": null,
  "payment_extra_ids": null,
  "amount_received": 0.00123,
  "actually_paid_at_fiat": 100,
  "fee": {
    "currency": "btc",
    "depositFee": 0,
    "withdrawalFee": 0,
    "serviceFee": 0
  }
}
200Any 2xx status acknowledges the delivery.
400Any other status makes Turmite retry on the schedule.

POSTpayout

A payout changed

Turmite sends the payout object to the `ipn_callback_url` of the withdrawal (or of its batch) on each status change, with the event `payout.<status>` in `x-turmite-event`. The key is the project IPN secret. The headers, signatures and retries are the same as for the payment webhook. `sent`, `failed`, `rejected` and `cancelled` are final events.

Parameters

x-turmite-sigheaderrequired
stringHex HMAC-SHA512 of the key-sorted JSON body. The key is the project IPN secret for an `ipn_callback_url`, or the endpoint secret for a project endpoint. The header name is a project setting. The default is `x-turmite-sig`.
x-turmite-timestampheaderrequired
stringUnix time in seconds when Turmite signed this attempt.
x-turmite-signatureheaderrequired
string`v1=` and the hex HMAC-SHA256 of `<x-turmite-timestamp>.<raw body>`. The key is the same as for the signature header.
x-turmite-eventheaderrequired
stringThe event name, such as `payment.finished`, `payout.sent` or `test`.
x-turmite-deliveryheaderrequired
stringThe delivery id. Retries of a delivery use the same id. Use it to ignore duplicates.
user-agentheaderrequired
string

Body

idrequired
string
batch_withdrawal_idrequired
string
addressrequired
string
extra_idrequired
string | null
currencyrequired
string
networkrequired
stringThe network code in lower case, such as `eth` or `tron`.
amountrequired
stringA decimal number as text.
feerequired
string | nullThe network fee in `fee_currency`, when known. The hot wallet pays it.
fee_currencyrequired
stringThe native coin of the network, such as `eth` or `trx`.
statusrequired
string`pending-otp-verification`: waits for a one-time code. An API batch waits for `verify`, or the admin who clicked Approve in the dashboard must enter the code that Turmite emailed. `pending-approval`: above a project limit; waits for an admin in the dashboard. `pending`: cleared to send. `signing`: signed and stored, no node took it yet. `initiated`: a node took the transaction. `sent`: on the chain with the network's confirmations. `sent`, `failed`, `rejected` and `cancelled` are final. `needs-review`: Turmite cannot tell whether the payout went out (its nonce is used by another transaction). An admin checks the chain and records the result.pending-approvalpending-otp-verificationpendingsigninginitiatedsentfailedrejectedcancelledneeds-review
hashrequired
string | nullThe transaction hash.
errorrequired
string | null
ipn_callback_urlrequired
string (uri) | null
payout_descriptionrequired
string | null
unique_external_idrequired
string | null
created_atrequired
string (date-time)
requested_atrequired
string (date-time) | null
updated_atrequired
string (date-time)

Request body

{
  "id": "5000248325",
  "batch_withdrawal_id": "5000000713",
  "address": "TQrZ9wBzhXnHdAdKwRBfdMH2RiTjH6yGtW",
  "extra_id": null,
  "currency": "usdttrc20",
  "network": "tron",
  "amount": "250",
  "fee": "4.4",
  "fee_currency": "trx",
  "status": "sent",
  "hash": "9f4c0e5b2a7d1c3e8f6a0b4d2c9e7f1a3b5d8c0e2f4a6b8d0c2e4f6a8b0d2c4e",
  "error": null,
  "ipn_callback_url": "https://shop.example.com/turmite/payout-ipn",
  "payout_description": "Refund for order 1042",
  "unique_external_id": "refund-1042",
  "created_at": "2026-10-23T13:00:00.000Z",
  "requested_at": "2026-10-23T13:01:10.000Z",
  "updated_at": "2026-10-23T13:02:45.000Z"
}
200Any 2xx status acknowledges the delivery.
400Any other status makes Turmite retry on the schedule.

POSTevent

An event for a project endpoint

Turmite sends this envelope to each endpoint that you add under Webhooks in the dashboard. `event` is `payment.<status>` with a payment in `data`, `payout.<status>` with a payout in `data`, or `test` with a message in `data`. Each endpoint has its own secret. The dashboard shows it. Turmite signs both signature headers with it. The headers, the signature rules and the retries are the same as for the payment webhook.

Parameters

x-turmite-sigheaderrequired
stringHex HMAC-SHA512 of the key-sorted JSON body. The key is the project IPN secret for an `ipn_callback_url`, or the endpoint secret for a project endpoint. The header name is a project setting. The default is `x-turmite-sig`.
x-turmite-timestampheaderrequired
stringUnix time in seconds when Turmite signed this attempt.
x-turmite-signatureheaderrequired
string`v1=` and the hex HMAC-SHA256 of `<x-turmite-timestamp>.<raw body>`. The key is the same as for the signature header.
x-turmite-eventheaderrequired
stringThe event name, such as `payment.finished`, `payout.sent` or `test`.
x-turmite-deliveryheaderrequired
stringThe delivery id. Retries of a delivery use the same id. Use it to ignore duplicates.
user-agentheaderrequired
string

Body

eventrequired
string`payment.<status>`, `payout.<status>` or `test`.
delivery_idrequired
stringThe same value as the `x-turmite-delivery` header.
created_atrequired
integer (int64)Unix time in seconds when Turmite made the event.
datarequired
any | object | object

Request body

{
  "event": "payment.finished",
  "delivery_id": "dK4rT8wQ2mN6xP1vB9cL5zH7",
  "created_at": 1761221644,
  "data": {
    "payment_id": 5077125051,
    "invoice_id": 4522625843,
    "payment_status": "finished",
    "pay_address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
    "payin_extra_id": null,
    "price_amount": 100,
    "price_currency": "usd",
    "pay_amount": 0.00123,
    "actually_paid": 0.00123,
    "pay_currency": "btc",
    "order_id": "1042",
    "order_description": "Order #1042",
    "purchase_id": "6084815412",
    "outcome_amount": 0.00123,
    "outcome_currency": "btc",
    "network": "btc",
    "network_precision": 8,
    "smart_contract": null,
    "payin_hash": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
    "payout_hash": null,
    "payment_url": "https://pay.example.com/pay/Q7mX2pK9vT4nB8cR1sW6yZ3h",
    "created_at": "2026-10-23T12:00:00.000Z",
    "updated_at": "2026-10-23T12:14:03.512Z",
    "expiration_estimate_date": "2026-10-23T12:15:00.000Z",
    "parent_payment_id": null,
    "type": "crypto2crypto",
    "time_limit": null,
    "burning_percent": null,
    "payment_extra_ids": null,
    "amount_received": 0.00123,
    "actually_paid_at_fiat": 100,
    "fee": {
      "currency": "btc",
      "depositFee": 0,
      "withdrawalFee": 0,
      "serviceFee": 0
    }
  }
}
200Any 2xx status acknowledges the delivery.
400Any other status makes Turmite retry on the schedule.