Reseller API · v1

Add crypto swaps to your product.

Use EagleSwap to quote a pair, create a swap, and track it through completion. The API uses straightforward JSON over HTTPS and is built for server-to-server integrations.

Base URL

https://eagleswap.to

Authentication

Bearer key

Format

JSON over HTTPS

Quickstart

One swap, start to finish

A typical integration has four calls. Keep the IDs from each response; you will need them in the next step.

  1. 01

    Fetch assets

    Store the assetId values returned by the catalog.

  2. 02

    Request a quote

    Send the amount as a decimal string: input for float, output for fixed.

  3. 03

    Create the swap

    Submit addresses before the quote expires.

  4. 04

    Track the order

    Poll by orderId until the status is final.

Quotes last at most 30 seconds; use the returned expiresAt rather than a timer. Be ready with the recipient address. A refund address is optional when the quote does not require one.

Authentication

Keep the API key on your server

Send your key in the Authorization header on every request. API keys can create real swaps, so never put one in browser code, a mobile app, analytics, or public logs.

Request header
Authorization: Bearer YOUR_API_KEY

Call EagleSwap from a backend you control.

Keep the key in a server-side secret manager. Approved partners can issue a replacement in the partner dashboard after draining active swaps; contact support if access is unavailable.

Rotate keys only after draining active swaps

Rotation revokes the old credential immediately. Quotes and swaps belong to the exact credential that created them, not just to the reseller account, so the new key cannot create a swap from an old quote or read the status of an old swap.

  1. Stop creating quotes and swaps with the old key.
  2. Keep polling every swap created with that key until it reaches a terminal status, and persist its final status and transaction IDs.
  3. Rotate the key only after no swaps are in flight. Save the new key when it is shown, install it in your secret manager, and deploy it immediately.
  4. Resume quote and swap creation with the new key. Retain your archived records because the old orders are no longer available through the API.
GET/api/v1/assets

List assets

Returns the assets and networks that are currently available. Fetch this list instead of saving asset IDs in your code. The IDs below are placeholders; this endpoint returns the opaque values to use in a quote.

cURL
curl https://eagleswap.to/api/v1/assets \
  -H "Authorization: Bearer YOUR_API_KEY"
200 response
{
  "assets": [
    {
      "assetId": "<btc_asset_id_from_assets>",
      "networkId": "<bitcoin_network_id_from_assets>",
      "symbol": "BTC",
      "decimals": 8,
      "networkName": "Bitcoin",
      "memoRequired": false
    }
  ]
}

Response fields

assetId
stringrequired

The asset ID to use in quote requests. Copy it exactly as returned.

networkId
stringrequired

The network ID for this asset. Use it to distinguish the same token on different networks. It is not a quote or swap request field.

symbol
stringrequired

The ticker, such as BTC or USDT. The same symbol can appear on more than one network.

decimals
integerrequired

The maximum number of decimal places accepted for this asset.

networkName
stringrequired

The network name to show in your UI.

memoRequired
booleanrequired

Whether this network can require a memo or tag. Follow the quote's requirements when creating a swap.

memoName
stringoptional

The label to show for a memo or tag field. Included only when a label is available.

POST/api/v1/quotes

Create a quote

Returns the price and requirements for a swap. Select assets by symbol and network name from the catalog, then pass their exact assetId values here. Send amounts as strings to preserve every decimal place.

Request body

originAssetId
stringrequired

The ID of the asset the customer sends.

destinationAssetId
stringrequired

The ID of the asset the customer receives.

swapType
float | fixedoptional

Which amount to fix. Omit it to use float, which fixes the amount sent. Use fixed to fix the amount received.

amount
decimal stringrequired

A value greater than zero, such as "0.01". For float, this is the amount sent. For fixed, this is the amount received.

cURL
curl -X POST https://eagleswap.to/api/v1/quotes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "originAssetId": "<btc_asset_id_from_assets>",
    "destinationAssetId": "<eth_asset_id_from_assets>",
    "swapType": "float",
    "amount": "0.01"
  }'
Fixed cURL
curl -X POST https://eagleswap.to/api/v1/quotes \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "originAssetId": "<btc_asset_id_from_assets>",
    "destinationAssetId": "<eth_asset_id_from_assets>",
    "swapType": "fixed",
    "amount": "0.25"
  }'
200 float response
{
  "quoteId": "<quote_id_from_quotes>",
  "swapType": "float",
  "input": {
    "assetId": "<btc_asset_id_from_assets>",
    "amount": "0.01"
  },
  "output": {
    "assetId": "<eth_asset_id_from_assets>",
    "estimatedAmount": "0.2481"
  },
  "expiresAt": "2026-08-22T12:00:30.000Z",
  "requirements": {
    "recipientMemoRequired": false,
    "refundAddressRequired": true,
    "refundMemoRequired": false
  }
}
200 fixed response
{
  "quoteId": "<fixed_quote_id_from_quotes>",
  "swapType": "fixed",
  "input": {
    "assetId": "<btc_asset_id_from_assets>",
    "amount": "0.0112"
  },
  "output": {
    "assetId": "<eth_asset_id_from_assets>",
    "estimatedAmount": "0.25"
  },
  "expiresAt": "2026-08-22T12:00:30.000Z",
  "requirements": {
    "recipientMemoRequired": false,
    "refundAddressRequired": true,
    "refundMemoRequired": false
  }
}

These are short-lived estimates, not a locked provider rate. Swap creation obtains a fresh execution quote and may choose another route. A float swap's output estimate or a fixed swap's required input may differ from the quote. Always display the created swap's payment instructions.

POST/api/v1/swaps

Create a swap

Turns an unexpired quote into payment instructions. Send a stable Idempotency-Key header for each intended order and retain it until the attempt is terminal. The execution price is refreshed, so read the returned payment amount rather than assuming it matches the quote.

Request body

quoteId
stringrequired

The ID of the quote to use. The quote must not be expired.

recipientAddress
stringrequired

The address that receives the output asset.

refundAddress
stringconditional

The address that receives a refund on the origin network. Send it when requirements.refundAddressRequired is true.

recipientMemo
stringoptional

A separate memo or tag for the recipient address. EagleSwap does not require it. If the memo is part of the address format, send the complete address instead.

refundMemo
stringconditional

Send it when requirements.refundMemoRequired is true and you provide a refund address. Never send it without refundAddress.

externalOrderId
stringoptional

Your own order reference. If provided, it must be unique within your reseller account.

If a request times out, poll GET /api/v1/order-attempts/{idempotencyKey}. Reusing the key with a different body returns 409 IDEMPOTENCY_CONFLICT.

A new order returns 201, and a completed replay returns the original successful status and body. PROCESSING or RECOVERING returns 202 with Retry-After and Location. Poll that URL instead of repeatedly posting. A safely failed pre-creation attempt is marked FAILED and permits a controlled retry with the same key and body.

Replace the bracketed addresses with complete chain addresses. Bracketed values are placeholders, not valid addresses.

cURL
curl -X POST https://eagleswap.to/api/v1/swaps \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Idempotency-Key: order-9481-attempt-1" \
  -H "Content-Type: application/json" \
  -d '{
    "quoteId": "<quote_id_from_quotes>",
    "recipientAddress": "<complete_recipient_address>",
    "refundAddress": "<complete_refund_address>",
    "externalOrderId": "order-9481"
  }'
201 response
{
  "orderId": "7k2m48p3x6",
  "externalOrderId": "order-9481",
  "swapType": "float",
  "status": "AWAITING_PAYMENT",
  "input": {
    "assetId": "<btc_asset_id_from_assets>",
    "amount": "0.01"
  },
  "output": {
    "assetId": "<eth_asset_id_from_assets>",
    "estimatedAmount": "0.2481"
  },
  "payment": {
    "assetId": "<btc_asset_id_from_assets>",
    "amount": "0.01",
    "address": "<deposit_address>",
    "expiresAt": "2026-08-22T12:30:00.000Z"
  },
  "fee": {
    "totalFeeBps": 40,
    "includedInRate": false
  },
  "createdAt": "2026-08-22T12:00:12.000Z",
  "updatedAt": "2026-08-22T12:00:12.000Z"
}

Show the payment object as-is

The customer must send the full payment.amount to payment.address by payment.expiresAt when provided. A fixed swap may require more input than its earlier quote showed. If payment.memo is present, show it beside the address—it is part of the deposit instructions.

GET/api/v1/swaps/{orderId}

Check a swap

Poll with the exact API credential that created the swap. Another credential for the same reseller account cannot access it. We recommend every 10–15 seconds while a swap is active. Unknown orders and orders owned by another credential both return the same 404 response.

cURL
curl https://eagleswap.to/api/v1/swaps/7k2m48p3x6 \
  -H "Authorization: Bearer YOUR_API_KEY"
200 response while output is being recalculated
{
  "orderId": "7k2m48p3x6",
  "externalOrderId": "order-9481",
  "swapType": "float",
  "status": "PAYMENT_RECEIVED",
  "input": {
    "assetId": "<btc_asset_id_from_assets>",
    "amount": "0.01"
  },
  "output": {
    "assetId": "<eth_asset_id_from_assets>",
    "estimatedAmount": null
  },
  "payment": {
    "assetId": "<btc_asset_id_from_assets>",
    "amount": "0.01",
    "address": "<deposit_address>",
    "expiresAt": "2026-08-22T12:30:00.000Z"
  },
  "fee": {
    "totalFeeBps": 40,
    "includedInRate": false
  },
  "transactions": {
    "inputTxId": "<input_transaction_id>"
  },
  "createdAt": "2026-08-22T12:00:12.000Z",
  "updatedAt": "2026-08-22T12:04:00.000Z"
}

The full swap object is returned on each check. output.estimatedAmount can temporarily be null after a deposit while the revised output is being calculated; do not show the old estimate as final. transactions and its individual transaction IDs appear only when known. The payment deadline is route-dependent; use the returned payment.expiresAt when present.

GET/api/v1/order-attempts/{idempotencyKey}

Check order creation

Use this endpoint after a create request returns 202 or the connection is lost. Active attempts return 202 and Retry-After; terminal attempts return 200. A completed attempt includes the original API response in response.

cURL
curl https://eagleswap.to/api/v1/order-attempts/order-9481-attempt-1 \
  -H "Authorization: Bearer YOUR_API_KEY"
202 recovery response
{
  "idempotencyKey": "order-9481-attempt-1",
  "internalOrderId": "swap_9b6b15b29e8d4a709db971480e5e994c",
  "state": "RECOVERING",
  "retryable": false,
  "createdAt": "2026-08-22T12:00:12.000Z",
  "updatedAt": "2026-08-22T12:00:17.000Z",
  "lastRecoveryAttemptAt": "2026-08-22T12:00:17.000Z"
}
AWAITING_PAYMENTWaiting for the customer deposit
PAYMENT_RECEIVEDDeposit seen on-chain
INCOMPLETE_DEPOSITDeposit seen, but below the required amount
PROCESSINGSwap is being executed
COMPLETEDOutput transaction sent
REFUNDEDInput returned to the refund address
FAILEDSwap stopped and could not complete
EXPIREDPayment window closed

Stop polling at COMPLETED, REFUNDED, FAILED, or EXPIRED. Transaction IDs appear in transactions as they become known.

Errors

One predictable error shape

Log the request ID on your server. It gives support a reliable way to trace a failed call without exposing customer data.

Error response
{
  "error": {
    "code": "QUOTE_EXPIRED",
    "message": "Quote expired or unavailable",
    "requestId": "request_4af127b83c9d46e5a021f79863bc80db"
  }
}
HTTPCodeWhat it means
400INVALID_REQUESTThe JSON body, request shape, or identifier format is invalid.
401AUTHENTICATION_REQUIREDNo bearer key was provided.
401INVALID_API_KEYThe bearer key is not valid.
403ACCOUNT_SUSPENDEDThe reseller account is not available.
404API_DISABLEDThe reseller API is not available.
404NOT_FOUNDThe swap was not found for this credential.
409IDEMPOTENCY_CONFLICTThe key or external order ID was already used.
410QUOTE_EXPIREDThe quote expired or does not belong to this credential.
422INVALID_REQUESTA quote amount is invalid, out of range, or has too many decimal places.
422INVALID_ASSETThe asset or pair is not supported.
422INVALID_ADDRESSA recipient or refund address is invalid.
422INVALID_MEMOA required memo is missing or cannot be used.
429RATE_LIMITEDThe request limit was reached.
500INTERNAL_ERRORThe request failed unexpectedly.
503INTERNAL_ERRORA required internal service is temporarily unavailable.
503QUOTE_UNAVAILABLEA quote could not be produced right now.
503SWAP_UNAVAILABLEThe swap could not be created right now.
503STATUS_UNAVAILABLEThe latest swap status could not be fetched.

Rate limits

Per-credential limits, per minute

List assets60 requests
Create quote60 requests
Create swap10 requests
Check status60 requests

Shared global and concurrency limits may also return 429 before your credential reaches its allowance. A 429 response includes a Retry-After header in seconds. Back off for that long before trying again.

Ready to build?

API access is available to approved reseller accounts.

Request access