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.

BucketWithout keyWith key (default)
Reads: assets, pairs, status60 / min / IP300 / min
Live quotes: /rate?amount=10 / min / IP60 / min
Creations and owner actionsowner actions only, 10 / min / IP10 / 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.

statusMeaning
awaiting_depositWaiting for the deposit. deposit_detected turns true as soon as it is seen.
confirmingDeposit seen, waiting for confirmations.required.
exchangingBeing exchanged; eta_minutes is an estimate.
sendingOutput broadcast to the destination.
completedDelivered: to.amount_received, transactions.delivery. Final.
action_requiredA new payout address is needed (see owner actions).
pausedDeposit below minimum or a return is being prepared.
refunded · expired · failedFinal. 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.

HTTPcode
401invalid_api_key · api_key_required
403batch_token_required
404not_found
409idempotency_conflict · in_progress
422invalid_request · amount_below_minimum · no_route
429rate_limited
502 · 503upstream_error · upstream_busy · upstream_unavailable · rate_unavailable