A single REST API for quotes, conversion, fiat on/off-ramp, custody, payouts and settlement. Predictable JSON, idempotent writes, and signed webhooks. Everything you need to integrate wholesale money movement.
The FleexPay API is organised around REST. It has predictable, resource-oriented URLs, accepts application/json request bodies, returns JSON responses, and uses standard HTTP response codes, authentication and verbs. All amounts are represented as decimal strings to avoid floating-point rounding (e.g. "50000.00"), and all timestamps are ISO-8601 in UTC.
The API is versioned in the path. The current stable version is v1.
| Environment | Base URL | Keys |
|---|---|---|
| Production | https://api.fleexpay.io/v1 | sk_live_… |
| Sandbox | https://sandbox.api.fleexpay.io/v1 | sk_test_… |
Authenticate by supplying your secret API key as a Bearer token in the Authorization header. You can create, roll and revoke keys from the FleexPay dashboard. Each key carries a set of scopes (e.g. quotes:write, payouts:write, custody:read).
curl https://api.fleexpay.io/v1/accounts \
-H "Authorization: Bearer sk_live_4f9c2a7b1e8d"pk_…) are read-limited and safe for hosted-flow widgets only.All POST requests that create or move money support idempotency. Pass a unique Idempotency-Key header (we recommend a UUID v4). If a request is retried with the same key within 24 hours, FleexPay returns the original response and never performs the action twice.
List endpoints are cursor-paginated. Use limit (1–100, default 25) and starting_after / ending_before with an object id.
{
"object": "list",
"data": [ /* … resources … */ ],
"has_more": true,
"next_cursor": "tx_9f2k7Lp0"
}FleexPay uses conventional HTTP status codes. Codes in the 2xx range indicate success, 4xx indicate a client error, and 5xx indicate a FleexPay-side error. Every error returns a structured body.
| Code | Meaning |
|---|---|
400 | Bad request — malformed JSON or invalid parameters |
401 | Unauthorized — missing or invalid API key |
403 | Forbidden — key lacks the required scope |
404 | Not found — resource does not exist |
409 | Conflict — idempotency or state conflict |
422 | Unprocessable — validation failed (e.g. insufficient funds) |
429 | Too many requests — rate limited |
500 | Server error — retry with backoff |
{
"error": {
"type": "insufficient_funds",
"message": "Account balance is below the requested amount.",
"param": "amount",
"request_id": "req_8Hk2p9Lm"
}
}The default limit is 100 requests/second per API key for reads and 50/second for writes. Limits are returned on every response via headers. When throttled you receive 429 with a Retry-After header.
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests in the window |
X-RateLimit-Remaining | Requests remaining |
X-RateLimit-Reset | Unix epoch when the window resets |
A customer represents an end-client you onboard onto FleexPay. Customers must pass KYC (individuals) or KYB (businesses) before they can transact. You may also use hosted onboarding flows.
curl https://api.fleexpay.io/v1/customers \
-H "Authorization: Bearer sk_live_•••" \
-H "Content-Type: application/json" \
-d '{
"type": "business",
"legal_name": "Acme Fintech Ltd",
"registration_number": "12345678",
"country": "GB",
"email": "[email protected]",
"contact": { "first_name": "Jordan", "last_name": "Lee" }
}'{
"id": "cus_2Nq8Xy",
"object": "customer",
"type": "business",
"legal_name": "Acme Fintech Ltd",
"country": "GB",
"kyc_status": "pending",
"created_at": "2026-06-30T11:58:04Z"
}| Field | Type | Notes |
|---|---|---|
type required | string | individual or business |
legal_name required | string | Full legal name |
country required | string | ISO 3166-1 alpha-2 |
email | string | Primary contact email |
registration_number | string | Business only |
An account holds balances across multiple assets (fiat and crypto) for you or a sub-ledgered customer. Retrieve balances to power dashboards and reconciliation.
{
"object": "list",
"account_id": "acc_5Tg1Wq",
"data": [
{ "currency": "EUR", "available": "182450.00", "pending": "0.00" },
{ "currency": "USDC", "available": "95120.50", "pending": "500.00" },
{ "currency": "BTC", "available": "3.10482000", "pending": "0.00000000" }
]
}A quote locks a wholesale exchange rate for a short window (typically 30 seconds). Reference the quote id when you execute a conversion to guarantee the rate.
curl https://api.fleexpay.io/v1/quotes \
-H "Authorization: Bearer sk_live_•••" \
-H "Content-Type: application/json" \
-d '{
"from_currency": "EUR",
"to_currency": "USDC",
"from_amount": "50000.00",
"side": "sell"
}'{
"id": "qt_3p9Xk2",
"object": "quote",
"from_currency": "EUR",
"to_currency": "USDC",
"from_amount": "50000.00",
"to_amount": "54160.00",
"rate": "1.0832",
"fee": { "currency": "EUR", "amount": "25.00" },
"side": "sell",
"status": "open",
"expires_at": "2026-06-30T12:00:30Z"
}| Field | Type | Notes |
|---|---|---|
from_currency required | string | Source asset |
to_currency required | string | Target asset |
from_amount | string | Provide either from_amount or to_amount |
to_amount | string | Desired output amount |
side | string | buy or sell |
Execute a previously created quote to perform the conversion. The debit and credit settle atomically against the account balance.
curl https://api.fleexpay.io/v1/conversions \
-H "Authorization: Bearer sk_live_•••" \
-H "Idempotency-Key: 7e1b9c44-2f0a-4c1e-9a3b-6d2f8a0c1e55" \
-H "Content-Type: application/json" \
-d '{ "quote_id": "qt_3p9Xk2", "account_id": "acc_5Tg1Wq" }'{
"id": "cnv_7Lm0Qa",
"object": "conversion",
"quote_id": "qt_3p9Xk2",
"from": { "currency": "EUR", "amount": "50000.00" },
"to": { "currency": "USDC", "amount": "54160.00" },
"rate": "1.0832",
"status": "settled",
"created_at": "2026-06-30T12:00:12Z"
}Create a deposit intent to receive fiat into a virtual account via bank rails. FleexPay returns the bank details (or a virtual IBAN) to present to the payer; funds credit automatically on receipt and fire a webhook.
curl https://api.fleexpay.io/v1/deposits \
-H "Authorization: Bearer sk_live_•••" \
-H "Content-Type: application/json" \
-d '{
"account_id": "acc_5Tg1Wq",
"currency": "EUR",
"method": "sepa",
"customer_id": "cus_2Nq8Xy"
}'{
"id": "dep_9Kx2Pe",
"object": "deposit",
"currency": "EUR",
"method": "sepa",
"status": "awaiting_funds",
"deposit_instructions": {
"account_holder": "FleexPay / Isla-Mia Blockchain Solutions LLC",
"iban": "DE89 3704 0044 0532 0130 00",
"bic": "COBADEFFXXX",
"reference": "FPX-9KX2PE"
},
"created_at": "2026-06-30T12:01:40Z"
}Create a payout to send fiat to a bank account or convert and pay out in stablecoin/crypto to a beneficiary. Payouts debit the account balance and can be funded directly or via a linked conversion.
curl https://api.fleexpay.io/v1/payouts \
-H "Authorization: Bearer sk_live_•••" \
-H "Idempotency-Key: 1c0d…f9" \
-H "Content-Type: application/json" \
-d '{
"account_id": "acc_5Tg1Wq",
"currency": "USD",
"amount": "25000.00",
"beneficiary_id": "ben_4Rt8Zo",
"rail": "swift",
"reference": "Invoice 8841"
}'{
"id": "pay_6Yh3Vn",
"object": "payout",
"currency": "USD",
"amount": "25000.00",
"fee": "12.00",
"beneficiary_id": "ben_4Rt8Zo",
"rail": "swift",
"status": "processing",
"estimated_arrival": "2026-07-01T16:00:00Z",
"created_at": "2026-06-30T12:03:11Z"
}| Field | Type | Notes |
|---|---|---|
account_id required | string | Source account |
currency required | string | Payout currency |
amount required | string | Decimal string |
beneficiary_id required | string | Pre-registered beneficiary |
rail | string | sepa · swift · ach · fps · onchain |
reference | string | Statement narrative |
Create custody wallets and generate deposit addresses. Keys are managed by FleexPay's MPC custody; you never handle private keys. Withdrawals require policy-based approval.
# request
{ "asset": "USDC", "network": "ethereum", "label": "treasury-1" }
# response
{
"id": "wlt_8Zc1Df",
"object": "wallet",
"asset": "USDC",
"network": "ethereum",
"address": "0x7A2f…9C41",
"balance": "0.00",
"custody": "mpc",
"created_at": "2026-06-30T12:04:50Z"
}Move digital assets out of a custody wallet to an external address. Transfers are screened against sanctions and travel-rule policy before broadcast.
# request
{
"wallet_id": "wlt_8Zc1Df",
"to_address": "0x91Bd…7E03",
"asset": "USDC",
"network": "ethereum",
"amount": "10000.00"
}
# response
{
"id": "trf_2Wq9Lk",
"object": "transfer",
"status": "pending_approval",
"amount": "10000.00",
"asset": "USDC",
"network_fee": "1.20",
"tx_hash": null,
"created_at": "2026-06-30T12:06:22Z"
}Register and reuse payout destinations — bank accounts or crypto addresses. Beneficiaries are validated and screened once, then referenced by id on payouts.
# request — bank beneficiary
{
"type": "bank",
"name": "Globex Trading Inc",
"currency": "USD",
"bank": {
"account_number": "000123456789",
"routing_number": "021000021",
"country": "US"
}
}
# response
{ "id": "ben_4Rt8Zo", "object": "beneficiary", "status": "active" }Every movement of value creates an immutable ledger transaction. Query the ledger for reconciliation, statements and reporting.
{
"object": "list",
"data": [
{
"id": "txn_0Aa1Bb",
"type": "conversion",
"direction": "debit",
"currency": "EUR",
"amount": "50000.00",
"balance_after": "132450.00",
"reference": "cnv_7Lm0Qa",
"created_at": "2026-06-30T12:00:12Z"
},
{
"id": "txn_0Cc2Dd",
"type": "deposit",
"direction": "credit",
"currency": "EUR",
"amount": "100000.00",
"balance_after": "182450.00",
"reference": "dep_9Kx2Pe",
"created_at": "2026-06-30T11:40:00Z"
}
],
"has_more": true,
"next_cursor": "txn_0Cc2Dd"
}Subscribe to events to receive real-time notifications. FleexPay sends a signed POST to your endpoint. Verify the FleexPay-Signature header (HMAC-SHA256 of the raw body using your webhook secret) before trusting the payload.
# request
{
"url": "https://api.yourapp.com/hooks/fleexpay",
"events": [ "deposit.completed", "payout.completed", "transfer.confirmed" ]
}
# response
{
"id": "whk_5Nm2Op",
"object": "webhook_endpoint",
"secret": "whsec_a1b2c3d4e5",
"status": "enabled"
}{
"id": "evt_7Qw3Er",
"object": "event",
"type": "payout.completed",
"created_at": "2026-07-01T16:02:10Z",
"data": {
"id": "pay_6Yh3Vn",
"status": "completed",
"amount": "25000.00",
"currency": "USD"
}
}const crypto = require('crypto');
function verify(rawBody, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}| Event | Fires when |
|---|---|
customer.kyc_updated | KYC/KYB status changes |
deposit.completed | Incoming fiat funds credited |
conversion.settled | A conversion settles |
payout.completed | A payout reaches the beneficiary |
payout.failed | A payout is returned or rejected |
transfer.confirmed | On-chain transfer confirmed |
wallet.deposit_received | Inbound crypto deposit detected |
Use sandbox keys (sk_test_…) against https://sandbox.api.fleexpay.io/v1. The sandbox mirrors production behaviour, issues test funds, and lets you simulate state transitions and webhooks without moving real money.
{ "account_id": "acc_5Tg1Wq", "currency": "EUR", "amount": "100000.00" }POST /v1/sandbox/events with an event type and the target object id.| Resource | Statuses |
|---|---|
| Quote | open · executed · expired |
| Conversion | pending · settled · failed |
| Deposit | awaiting_funds · completed · returned |
| Payout | processing · completed · failed · returned |
| Transfer | pending_approval · broadcasting · confirmed · failed |
| Customer | pending · approved · rejected · review |
Request sandbox access today and start integrating in minutes. Our solutions engineers will help you go live.
Request access →