SmallSwap SmallSwap

API Reference / GET /new_trade

GET /api/v1/new_trade

Create a swap. Issues a deposit address and locks in a rate. Floating-rate by default.

Why GET, not POST?

Trocador uses GET with query parameters for swap creation, and Cake's TrocadorExchangeProvider is hard-wired to that. We mirror the convention so an existing Trocador integration works with a base-URL change. Idempotency-Key is still required.

Request

curl 'https://smallswap.example/api/v1/new_trade?ticker_from=xmr&ticker_to=usdt&network_from=monero&network_to=tron&amount_from=1.0&address=TWdYcN...&refund=4Bd...' \
  -H 'API-Key: prt_yourkeyhere' \
  -H 'Idempotency-Key: 7d4f2c1a-9e8b-4d3f-a7c2-1e6b9f3d8a4c'

Query parameters

NameRequiredDescription
ticker_fromyesSource ticker.
ticker_toyesDestination ticker.
network_fromyesSource chain.
network_toyesDestination chain.
amount_fromone ofAmount of ticker_from. Decimal string.
amount_toone ofAmount of ticker_to. Fixed-rate mode (MVP rejects with 503).
paymentnoTrue = fixed-rate, False = floating (default).
idconditionalRequired for fixed-rate. Rate ID returned from /new_rate as trade_id.
providernoProvider name. Default: best-selected by routing policy.
markupnoBasis points credited to caller's commission account. Capped per-key.
min_kycratingnoTrocador compat. Accepted and ignored.
addressyesReceiving address (where we send swap output).
refundyesRefund address. If the swap can't complete, funds return here. Required.
refund_memonoMemo for refund address on chains that need it. Cake passes '0' by default.
extra_idnoMemo / destination tag for address.
webhook_urlnoPartner-only. HTTPS or .onion URL we POST status changes to.
notenoFree-form caller metadata. We echo it back unparsed.

Required header

Idempotency-Key: opaque, ≤128 chars, recommended UUID4. Repeats with same key + same query string return the same response. Different query string with the same key errors with idempotency_conflict.

Response — 201 Created

{
  "trade_id": "7K3M9P2X8B4Q5R6S",
  "status": "pending",
  "ticker_from": "xmr",
  "ticker_to": "usdt",
  "network_from": "monero",
  "network_to": "tron",
  "amount_from": "1.0",
  "amount_to": "398.32",
  "rate": "398.32",
  "provider": "SmallSwap",
  "risk": "precheck",
  "id_provider": "ss_01HZJ4G...",
  "address_provider": "4AfUP...",
  "address_provider_memo": null,
  "refund_address": "4Bd...",
  "address_user": "TWdYcN...",
  "password": "8c4f0e2a1b9d7e6f5a3c2b1d0e9f8a7b",
  "date": "2026-05-13T15:50:00Z",
  "deposit_window_seconds": 3600,
  "expires_at": "2026-05-13T16:50:00Z",
  "explorer_url_deposit": null,
  "explorer_url_payout": null
}
  • address_provider = deposit address (where the user sends funds; we are the "provider").
  • address_provider_memo = extra ID / destination tag for chains that need it (some XRP setups).
  • address_user = receiving address (where we send output).
  • password = per-trade lookup secret. 32-char hex. Provide it to /trade?id=… for fetch-without-API-key.
  • id_provider = our internal swap ID, distinct from trade_id. Matches Trocador's separation between aggregator-side and sub-provider-side IDs.
  • deposit_window_seconds = 3600. After expires_at, the swap transitions to expired and any subsequently-received deposit is refunded.

Error responses

HTTPcodeWhen
400invalid_parameterMissing fields, bad address format.
400idempotency_conflictSame key, different query string.
409quote_expiredid (rate ID) past its expires_at (fixed-rate only).
422address_invalidaddress or refund fails server-side format check.
422address_blockedaddress, refund, or deposit-origin is on the OFAC SDN list. Applies to all routes including SmallSwap-self-fill.
503route_unavailableThe chosen provider can no longer fill.
503fixed_rate_unsupportedpayment=True requested; MVP is floating-rate only.
429rate_limit_exceededCaller over rate limit.