Overview
Base URL https://alchimex.io/api/v1. JSON in, JSON out. Amounts are decimal strings, never floats. The machine-readable description is at /api/v1/openapi.json (OpenAPI 3.1).
- Reading (assets, pairs, rates, batch status) needs no key.
- Creating a batch needs a key. The rate is fixed at creation and held until
deposit.expires_at; the 0.5% lab fee is already inside every quote. - No account, no customer data: a batch is an asset pair, an amount and addresses. Nothing else is asked or stored.
Keys and limits
Send the key as Authorization: Bearer ax_… or X-Api-Key: ax_…. Keep it server-side: it can create batches billed to your integration.
| Bucket | Without key | With key (default) |
|---|---|---|
| Reads: assets, pairs, status | 60 / min / IP | 300 / min |
| Live quotes: /rate?amount= | 10 / min / IP | 60 / min |
| Creations and owner actions | owner actions only, 10 / min / IP | 10 / min |
Over the limit: 429 rate_limited with Retry-After. Higher limits are set per key on request.
Assets and pairs
Assets are addressed by code, network included: BTC, ETH, XMR, SOL, TRX, ZEC, BNB, ETH-ARB, ETH-BASE, ETH-RHC, USDT, USDT-TRX, USDT-ARB, USDT-BASE, USDT-BSC, USDT-SOL, USDC, USDC-ARB, USDC-BASE, USDC-BSC, USDC-SOL, USDC-TRX.
GET https://alchimex.io/api/v1/assets
GET https://alchimex.io/api/v1/pairs
/assets gives each code's symbol, network, decimals, contract and address regex (validate before you call). /pairs lists every routable pair with its indicative formula, minimum and median batch time, refreshed every minute.
Rates
# indicative formula, no upstream call
GET https://alchimex.io/api/v1/rate?from=BTC&to=XMR
# live quote for an exact amount, fee included (cached 20 s)
GET https://alchimex.io/api/v1/rate?from=BTC&to=XMR&amount=0.01
{
"from": "BTC", "to": "XMR", "type": "quote",
"amount_from": "0.01", "amount_to": "3.104213", "rate": "310.421",
"fee_percent": 0.5, "fee_included": true, "min_amount_usd": 12,
"quoted_at": "2026-10-26T14:02:11+00:00", "valid_for": 20
}
Create a batch
curl -X POST https://alchimex.io/api/v1/batches \
-H "Authorization: Bearer ax_…" \
-H "Idempotency-Key: 8d3f0c1e-…" \
-H "Content-Type: application/json" \
-d '{"from":"BTC","to":"XMR","amount":"0.01",
"destination_address":"48…","refund_address":"bc1q…"}'
Answer 201 with the batch, its deposit address and amount, and a batch_token. Show the deposit to your user; the rate holds until deposit.expires_at.
Idempotency-Key (recommended): retrying with the same key and body returns the same batch and the same batch_token (200, header Idempotent-Replayed: true). The same key with another body is a 409 idempotency_conflict. Without the header, a lost response means a lost token.
Follow a batch
GET https://alchimex.io/api/v1/batches/AX-7F3Q-21
Poll every 15–30 s until final is true. The reference alone shows the status, amounts and deposit address; the destination and refund addresses are masked unless you send X-Batch-Token.
| status | Meaning |
|---|---|
| awaiting_deposit | Waiting for the deposit. deposit_detected turns true as soon as it is seen. |
| confirming | Deposit seen, waiting for confirmations.required. |
| exchanging | Being exchanged; eta_minutes is an estimate. |
| sending | Output broadcast to the destination. |
| completed | Delivered: to.amount_received, transactions.delivery. Final. |
| action_required | A new payout address is needed (see owner actions). |
| paused | Deposit below minimum or a return is being prepared. |
| refunded · expired · failed | Final. A refund carries transactions.refund. |
Owner actions
PUT https://alchimex.io/api/v1/batches/AX-7F3Q-21/refund-address
PUT https://alchimex.io/api/v1/batches/AX-7F3Q-21/payout-address
X-Batch-Token: …
{"address": "…"}
Authorised by the batch token, not by the API key: you can hand a batch over to your user's own device without sharing your key. The payout address can only be set while the status is action_required.
Errors
{ "error": { "code": "amount_below_minimum", "message": "…", "min_amount_usd": 12 } }
Rely on code; messages are for humans and may change.
| HTTP | code |
|---|---|
| 401 | invalid_api_key · api_key_required |
| 403 | batch_token_required |
| 404 | not_found |
| 409 | idempotency_conflict · in_progress |
| 422 | invalid_request · amount_below_minimum · no_route |
| 429 | rate_limited |
| 502 · 503 | upstream_error · upstream_busy · upstream_unavailable · rate_unavailable |