API Integration Guidev1
Back to site
API Overview
CryptoSwap has two API surfaces. Public Data is for display and monitoring. Partner API is for approved partners that create swaps, track swaps, and read partner commission results.
REST JSON Public data: no key Partner API: key required Clearnet API allowed Onion portal login only
Choose the right surface

Public data can be used openly. Partner swap actions belong on your backend and require a partner key.

Public Data API

No API key required

https://b1exch.to/api

Use these endpoints for rates, liquidity, and public currency metadata. They are display-only and do not create swaps.

GET /api/liquidity GET /api/rates GET /api/currencies
Partner API

API key required

https://b1exch.to/api/partner/v1

Use this for server-side integrations that create swaps, track partner-owned swaps, and read partner commission results.

GET /api/partner/v1/me POST /api/partner/v1/quote POST /api/partner/v1/swaps GET /api/partner/v1/aml/screen/{address}
Only showing prices or availability?

Use Public Data. No account or key is needed.

Creating swaps for users?

Use Partner API from your backend with an API key on every request.

Handing this to AI?

Use the AI integration section for one copyable Markdown block.

Authentication
Every endpoint under /api/partner/v1 requires an API key on every request, including GET requests. Public market-data endpoints under /api/rates, /api/currencies, and /api/liquidity do not require a key.
No key yet? Buy a lifetime partner key for $100 in crypto at /buy-api-key. It is issued automatically once your payment confirms, with no account required.
Important: API keys are bearer secrets. Never put them in browser JavaScript, mobile apps distributed to users, or public repositories. Call the partner API from your backend server.
Headers for all partner API calls
X-API-Key: b1x_your_partner_key

# Alternative form, also accepted:
Authorization: Bearer b1x_your_partner_key

Scopes

Keys can be limited by operators. If a key lacks the needed scope, the API returns 403.

ScopeAllows
quotes:readCurrencies and quote preview
swaps:createCreate a new swap
swaps:readList, view, and delete visible swaps
aml:readScreen a wallet address for AML/compliance risk

Clearnet vs Onion

API traffic may come from clearnet when you use a clearnet API hostname provided by the operator. If this page shows an .onion base URL, clearnet-only servers need the clearnet API host instead. Partner portal login remains onion-only.

Minimal authenticated GET
curl https://b1exch.to/api/partner/v1/me \
  -H "X-API-Key: b1x_your_partner_key"
Liquidity
Enabled
Use this public endpoint to decide whether to show an asset as available before a customer starts a swap. Balances are rounded and intentionally approximate.
GET/api/liquidityNo API key

Best used for UI availability badges, exchange monitor feeds, and hiding temporarily unavailable assets.

Try it live
curl https://b1exch.to/api/liquidity
StatusMeaning
availableReady for normal swaps
lowAvailable, but keep customer amounts small
unavailableDo not offer this asset right now
disabledAsset is administratively disabled
Exchange Rates
Enabled
Use rates for display and monitoring. They are not binding swap quotes. Partner swap creation always recalculates a fresh quote.
GET/api/ratesNo API key
Try it live
# All pairs
curl https://b1exch.to/api/rates

# One pair
curl "https://b1exch.to/api/rates?from=BTC&to=XMR"

# Aggregator formats
curl https://b1exch.to/api/rates.xml
curl https://b1exch.to/api/rates.csv
ParameterUse
fromFilter by source currency, for example BTC
toFilter by destination currency, for example XMR
formatOptional json, xml, or csv
Supported Currencies
Enabled
Public currencies are useful for UI labels. Partner currencies include the minimum USD value enforced when creating partner API swaps.
GET/api/currenciesNo API key
curl https://b1exch.to/api/currencies
GET/api/partner/v1/currenciesAPI key required · scope quotes:read
curl https://b1exch.to/api/partner/v1/currencies \
  -H "X-API-Key: b1x_your_partner_key"
Show sample response
{
  "success": true,
  "currencies": [
    {
      "code": "BTC",
      "name": "Bitcoin",
      "decimals": 8,
      "enabled": true,
      "public_minimum_amount": 0.0001,
      "partner_api_minimum_usd": 20.00
    },
    {
      "code": "USDT_TRC20",
      "name": "Tether TRC20",
      "decimals": 6,
      "enabled": true,
      "public_minimum_amount": 1.00,
      "partner_api_minimum_usd": 50.00
    }
  ]
}
BTCBitcoin
LTCLitecoin
ETHEthereum
XMRMonero
SOLSolana
BCHBitcoin Cash
DAIDai ERC20
USDT_ERC20Tether ERC20
USDT_TRC20Tether TRC20
USDC_ERC20USD Coin ERC20
Partner Swaps
These are the endpoints most partner integrations use. Every request in this section must include X-API-Key or Authorization: Bearer.
Recommended swap creation flow

Use this as the integration blueprint. POST /quote is only a preview; POST /swaps creates the live swap and recalculates pricing at that moment. Then the client polls until is_completed is true.

1
Prepare Verify key and load limits GET /me GET /currencies
2
Preview Show estimated output POST /quote

Not a reservation.

3
Create Create the live swap POST /swaps

Store ID and deposit address.

4
Collect Customer pays deposit deposit_address

Respect expires_at.

5
Track Poll status GET /swaps/{id}

Stop at is_completed.

GET/api/partner/v1/meCheck key/accountStep 1

Call this once on startup or in your admin integration screen to verify the key works and to read the key's pending swap cap.

curl https://b1exch.to/api/partner/v1/me \
  -H "X-API-Key: b1x_your_partner_key"
Show sample response
{
  "success": true,
  "partner": {
    "id": "7a7a0000-0000-0000-0000-000000000000",
    "username": "example_partner",
    "display_name": "Example Partner",
    "api_enabled": true,
    "default_commission_percent": 2.0
  },
  "api_key": {
    "id": "8b8b0000-0000-0000-0000-000000000000",
    "name": "Production key",
    "key_prefix": "b1x_abcd...",
    "scopes": "quotes:read swaps:create swaps:read",
    "commission_percent": 2.0,
    "max_pending_swaps": 100
  },
  "limits": {
    "max_pending_swaps": 100
  }
}
POST/api/partner/v1/quotePreview onlyStep 2

Use this before showing a confirmation screen. It returns expected output and fees, but the result is not binding. When you later call POST /api/partner/v1/swaps to create the live swap, pricing is recalculated at that moment.

curl -X POST https://b1exch.to/api/partner/v1/quote \
  -H "Content-Type: application/json" \
  -H "X-API-Key: b1x_your_partner_key" \
  -d '{
    "from": "BTC",
    "to": "LTC",
    "amount": 0.01,
    "destination": "ltc1q..."
  }'
Show sample response
{
  "success": true,
  "quote_id": "0b41c7e4a58d4f0a",
  "from_currency": "BTC",
  "to_currency": "LTC",
  "amount": 0.01,
  "amount_usd": 640.00,
  "quoted_output": 1.234567,
  "min_output": 1.209876,
  "exchange_rate": 123.4567,
  "service_fee_percent": 1.0,
  "service_fee_usd": 6.40,
  "exchange_fee_usd": 2.15,
  "network_fee": 0.0001,
  "estimated_minutes": 15,
  "expires_in_seconds": 120,
  "binding": false,
  "note": "Quotes are indicative. POST /api/partner/v1/swaps calculates fresh pricing at request time."
}
POST/api/partner/v1/swapsCreate live swapStep 3

Create a real swap and show the returned deposit address to the customer. A refund address is required for API swaps. Use a unique reference for your order ID so network retries can be handled safely.

curl -X POST https://b1exch.to/api/partner/v1/swaps \
  -H "Content-Type: application/json" \
  -H "X-API-Key: b1x_your_partner_key" \
  -d '{
    "from": "BTC",
    "to": "LTC",
    "amount": 0.01,
    "destination": "ltc1q_customer_destination...",
    "refund_address": "bc1q_customer_refund...",
    "reference": "order-123",
    "commission_address": "bc1q_partner_commission..."
  }'
FieldRequiredMeaning
fromYesCurrency the customer will deposit
toYesCurrency sent to the customer destination
amountYesExpected source amount the customer should send
destinationYesCustomer payout address for the target currency
refund_addressYesCustomer refund address for the source currency
referenceRecommendedYour unique order ID, max 100 characters. Reusing the same reference with the same API key and same request returns the existing swap; reusing it with different details returns a duplicate-reference error.
commission_addressNoSame-chain address for automatic commission payout. If omitted, payable commission is held in the partner balance for manual payout.
Show sample response
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "waiting_for_deposit",
    "is_completed": false,
    "outcome": null,
    "from_currency": "BTC",
    "to_currency": "LTC",
    "deposit_address": "bc1q_customer_deposit...",
    "destination_address": "ltc1q_customer_destination...",
    "refund_address": "bc1q_customer_refund...",
    "amount": 0.01,
    "deposit_amount": null,
    "quoted_output": 1.234567,
    "min_output": 1.209876,
    "exchange_rate": 123.4567,
    "service_fee_percent": 1.0,
    "output_amount": null,
    "deposit_confirmations": 0,
    "output_confirmations": 0,
    "deposits": [],
    "outputs": [],
    "refund": null,
    "reference": "order-123",
    "expires_at": "2026-05-15T13:40:00Z",
    "completed_at": null,
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "automatic_address",
      "payout_currency": "BTC",
      "payout_address": "bc1q_partner_commission..."
    },
    "commission": null
  }
}
GET/api/partner/v1/swaps/{id}Track one swapStep 5

Poll this endpoint after creation. Use is_completed as the stop flag; status stays intentionally simple.

curl https://b1exch.to/api/partner/v1/swaps/00000000-0000-0000-0000-000000000000 \
  -H "X-API-Key: b1x_your_partner_key"
Show sample response
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "completed",
    "is_completed": true,
    "outcome": "success",
    "from_currency": "BTC",
    "to_currency": "LTC",
    "deposit_address": "bc1q_customer_deposit...",
    "destination_address": "ltc1q_customer_destination...",
    "refund_address": "bc1q_customer_refund...",
    "amount": 0.01,
    "deposit_amount": 0.01,
    "quoted_output": 1.234567,
    "min_output": 1.209876,
    "exchange_rate": 123.4567,
    "service_fee_percent": 1.0,
    "output_amount": 1.232100,
    "deposit_confirmations": 3,
    "output_confirmations": 1,
    "deposits": [
      {
        "txid": "8c63fc...",
        "currency": "BTC",
        "amount": 0.006,
        "confirmations": 3,
        "address": "bc1q_customer_deposit..."
      },
      {
        "txid": "51a0ab...",
        "currency": "BTC",
        "amount": 0.004,
        "confirmations": 3,
        "address": "bc1q_customer_deposit..."
      }
    ],
    "outputs": [
      {
        "txid": "98b7ad...",
        "currency": "LTC",
        "amount": 1.232100,
        "confirmations": 1,
        "address": "ltc1q_customer_destination..."
      }
    ],
    "reference": "order-123",
    "completed_at": "2026-05-15T13:22:11Z",
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "partner_balance"
    },
    "commission": {
      "status": "payable",
      "payable": true,
      "payout_method": "partner_balance",
      "amount_usd": 2.41,
      "commission_percent": 2.0,
      "message": null
    }
  }
}
Show processing example
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "processing",
    "is_completed": false,
    "from_currency": "BTC",
    "to_currency": "LTC",
    "deposit_address": "bc1q_customer_deposit...",
    "destination_address": "ltc1q_customer_destination...",
    "refund_address": "bc1q_customer_refund...",
    "amount": 0.01,
    "deposit_amount": 0.01,
    "deposit_confirmations": 1,
    "output_confirmations": 0,
    "deposits": [
      {
        "txid": "8c63fc...",
        "currency": "BTC",
        "amount": 0.01,
        "confirmations": 1,
        "address": "bc1q_customer_deposit..."
      }
    ],
    "outputs": [],
    "reference": "order-123",
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "automatic_address",
      "payout_currency": "BTC",
      "payout_address": "bc1q_partner_commission..."
    }
  }
}
Show paid commission example
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "completed",
    "is_completed": true,
    "outcome": "success",
    "from_currency": "BTC",
    "to_currency": "LTC",
    "deposit_amount": 0.01,
    "output_amount": 1.232100,
    "outputs": [
      {
        "txid": "98b7ad...",
        "currency": "LTC",
        "amount": 1.232100,
        "confirmations": 1,
        "address": "ltc1q_customer_destination..."
      }
    ],
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "automatic_address",
      "payout_currency": "BTC",
      "payout_address": "bc1q_partner_commission..."
    },
    "commission": {
      "status": "paid",
      "payable": true,
      "payout_method": "automatic_address",
      "amount_usd": 1.27,
      "commission_percent": 2.0,
      "payout_currency": "BTC",
      "payout_address": "bc1q_partner_commission...",
      "payout_txid": "f7b2c1...",
      "created_at": "2026-05-15T13:22:30Z",
      "available_at": "2026-05-15T13:24:10Z",
      "paid_at": "2026-05-15T13:25:02Z"
    }
  }
}
Show payout requested example
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "completed",
    "is_completed": true,
    "outcome": "success",
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "partner_balance"
    },
    "commission": {
      "status": "payout_requested",
      "payable": true,
      "payout_method": "manual_payout",
      "amount_usd": 18.50,
      "commission_percent": 2.0,
      "payout_currency": "LTC",
      "payout_address": "ltc1q_partner_manual_payout...",
      "created_at": "2026-05-15T13:22:30Z",
      "available_at": "2026-05-15T13:24:10Z"
    }
  }
}
Show no-commission example
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "completed",
    "is_completed": true,
    "outcome": "success",
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "automatic_address",
      "payout_currency": "BTC",
      "payout_address": "bc1q_partner_commission..."
    },
    "commission": {
      "status": "not_payable",
      "payable": false,
      "payout_method": "automatic_address",
      "amount_usd": 0,
      "commission_percent": 2.0,
      "reason_code": "not_payable",
      "message": "No commission was payable for this swap."
    }
  }
}
Show refunded example
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "refunded",
    "is_completed": true,
    "outcome": "refunded",
    "from_currency": "BTC",
    "to_currency": "LTC",
    "deposit_address": "bc1q_customer_deposit...",
    "destination_address": "ltc1q_customer_destination...",
    "refund_address": "bc1q_customer_refund...",
    "refund": {
      "txid": "4e5c12...",
      "amount": 0.0098,
      "currency": "BTC",
      "address": "bc1q_customer_refund...",
      "reason": "Swap refunded",
      "refunded_at": "2026-05-15T13:22:11Z"
    },
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "partner_balance"
    }
  }
}
GET/api/partner/v1/swapsDashboard/reconcileAfterwards

Use for dashboards and reconciliation. Supports pagination and optional status filtering.

curl "https://b1exch.to/api/partner/v1/swaps?skip=0&take=50" \
  -H "X-API-Key: b1x_your_partner_key"

curl "https://b1exch.to/api/partner/v1/swaps?status=completed" \
  -H "X-API-Key: b1x_your_partner_key"
Show sample response
{
  "success": true,
  "total": 1,
  "loaded": 1,
  "has_more": false,
  "swaps": [
    {
      "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
      "short_id": "246fb837",
      "status": "completed",
      "is_completed": true,
      "outcome": "success",
      "from_currency": "BTC",
      "to_currency": "LTC",
      "amount": 0.01,
      "reference": "order-123",
      "commission_settings": {
        "percent": 2.0,
        "payout_method": "partner_balance"
      },
      "commission": {
        "status": "payable",
        "payable": true,
        "payout_method": "partner_balance",
        "amount_usd": 2.41,
        "commission_percent": 2.0
      }
    }
  ]
}
DELETE/api/partner/v1/swaps/{id}Delete from partner viewsOptional

Removes the swap from partner API and portal views. Treat this as permanent from the partner side. It does not cancel an already-created live swap.

curl -X DELETE https://b1exch.to/api/partner/v1/swaps/00000000-0000-0000-0000-000000000000 \
  -H "X-API-Key: b1x_your_partner_key"
AML Screening
Screen a wallet address for sanctions, illicit-source exposure, and risk signals before you accept or pay out to it. Results are advisory only and are not legal or compliance advice. Each call performs a live provider lookup, so this endpoint requires the aml:read scope (operators grant it per key) and is rate-limited per key.
GET/api/partner/v1/aml/screen/{address}API key required · scope aml:read

The chain is auto-detected from the address. For EVM addresses (0x…), which are valid on many chains, pass network to choose the chain to screen.

ParameterUse
addressPath. The wallet address to screen (16–128 chars).
networkQuery, optional. Chain for EVM addresses: ethereum, bsc, polygon, avalanche, arbitrum, optimism, base. Omit to auto-detect (correct for BTC, LTC, XMR, SOL, TRON, etc.). Unknown values fall back to auto-detect.
depthQuery, optional. Exposure-tracing hops, 110 (default 1). Higher depth follows the funds through more intermediaries (deepens exposure.indirect) but is slower. Out-of-range values are clamped.
curl https://b1exch.to/api/partner/v1/aml/screen/0x722122dF12D4e14e13Ac3b6895a86e84145b6967?network=ethereum \
  -H "X-API-Key: b1x_your_partner_key"
Show sample response
{
  "success": true,
  "address": "0x722122dF12D4e14e13Ac3b6895a86e84145b6967",
  "network": "ethereum",
  "depth": 1,
  "report": {
    "subject": { "address": "0x7221…b6967", "chain": "ethereum", "candidate_chains": ["ethereum","bsc","polygon"] },
    "score": 100,
    "band": "severe",
    "action": "block",
    "action_rationale": "Direct exposure to a sanctioned mixer.",
    "intel": { "entity": "Tornado Cash", "entity_type": "mixer", "tags": ["sanctioned","mixer"] },
    "activity": { "symbol": "ETH", "balance": 0.0, "tx_count": 143973, "total_received": 1119.22 },
    "exposure": {
      "direct": [ { "category": "mixer", "fraction": 0.91 } ],
      "indirect": [ { "category": "scam", "fraction": 0.04, "hops": 2, "direction": "inbound" } ]
    },
    "sources": [ { "name": "ofac-sdn", "authority": "US Treasury" } ],
    "disclaimer": "Advisory only. Not legal or compliance advice.",
    "content_hash": "532b4275…442943",
    "timestamp_utc": "2026-06-27T00:00:00Z"
  }
}

The sample is abbreviated. The full report object may also include concentration, flow, transactions, tokens, cross_chain_links, hits, warnings, analyzers, thresholds, check_mode, report_id, and scoring_model_version. Read fields defensively — treat any field as optional.

Risk bands & actions
bandactionMeaning
lowallowNo risk signals on the sources consulted.
mediumreviewSome exposure — consider enhanced due diligence.
highblockPendingReviewElevated risk — may warrant blocking.
severeblock / fileSarSanctions/illicit exposure — may warrant blocking or a report.

Treat action as a suggestion for your own policy, not an instruction. score is 0–100. A 404 with code no_screening_data means the address has no history on the sources consulted (often a clean, unused address). Transient provider/network issues return 503 service_unavailable — retry.

Latency: screening runs a live multi-source lookup and typically completes in 5–30 seconds, but a deep screen (high depth on an active address) can take up to ~2 minutes. Set your HTTP client timeout to at least 180 seconds and call this endpoint server-side, not in a user's request path. Note: requests through the clearnet (Cloudflare) API host are capped near 100s — use the .onion API host for the deepest screens. The content_hash in the report lets you store a tamper-evident record of each result.

Integration Details
These rules help avoid duplicate swaps, stale pricing mistakes, and confusing user experiences.

Quotes are not reservations

/quote is for preview. /swaps recalculates pricing and may return a different output if markets moved.

Retry safety

Send a unique reference per order. If a network timeout happens after creation, retrying the same request with the same key and reference returns the existing swap instead of creating a duplicate.

Pending cap is per key

If one API key reaches its pending swap cap, only that key is blocked. Use separate keys for separate apps or traffic sources.

Commission payout methods

If commission_address is provided, payout costs are deducted from the partner share. If omitted, payable commission is held in the partner balance. Manual payout requests are handled from the Partner Portal, not the swap API.

Currency rules

Use GET /api/partner/v1/currencies as the source of truth for enabled assets, decimal display, public minimum amounts, and partner API minimum USD values.

Polling

Poll one swap every 20-60 seconds. Avoid aggressive loops. Use the list endpoint for dashboards.

Simple Status Model

  1. waiting_for_deposit

    Deposit address has been created and the customer has not paid yet.

  2. processing

    Funds were seen or confirmed and the swap is moving through execution.

  3. completed

    Customer payout is complete. is_completed is true and outcome is success.

  4. expired / refunded / failed

    The swap is finished without a payout. Stop polling and show the returned result.

REFSwap response contractDocumented public values

Partner swap responses return partner-safe operational fields: customer addresses, quote amounts, public status, deposit transactions, customer payout transactions, refund details, captured commission settings, and partner commission result. Internal routing, liquidity, settlement, revenue, cost, and margin fields are not returned.

Success responses use a stable shape. Fields that are not available yet are returned as null where applicable, and transaction collections such as deposits and outputs are always arrays.

Status values

ValueMeaning
waiting_for_depositDeposit address is open and no accepted deposit is confirmed yet
processingDeposit or payout is in progress
completedCustomer payout completed
expiredNo accepted deposit arrived before expiry
refundedFunds were returned to the refund address
failedSwap ended with an operator-visible failure

Commission values

FieldValues
commission.statuspending, payable, payout_requested, paid, not_payable
payout_methodpartner_balance, automatic_address, manual_payout
reason_codebelow_minimum, not_payable, or omitted
Field groupReturned fields
Identityid, short_id, reference, created_at, expires_at, completed_at
Pair and amountsfrom_currency, to_currency, amount, deposit_amount, quoted_output, min_output, output_amount, exchange_rate
Addressesdeposit_address, destination_address, refund_address
Transactionsdeposits[] and outputs[]. Each item can include txid, currency, amount, confirmations, address, and UTXO vout when known.
Refundsrefund is included only when refund data exists. It can include txid, amount, currency, address, reason, and refunded_at.
Commissioncommission_settings shows the percent and payout method captured at swap creation. commission shows the later payout result when calculated.
Errors
Partner API application errors are JSON. Always check HTTP status first, then read code for machine handling and message or error for display/logging.
StatusMeaningWhat to do
400Validation failedFix the request body, amount, pair, or address.
401Missing/invalid API keySend X-API-Key on this request.
403Scope or account blockedUse a key with the needed scope or contact an operator.
404Not foundThe swap is not visible to this key/partner or the ID is wrong.
409Duplicate reference conflictThe same reference was reused with different swap details. Use a unique reference per order.
429Rate/pending limitBack off. too_many_pending_swaps (POST /swaps) means wait for this key's pending swaps to complete or expire; rate_limited (aml/screen) means slow your request rate.
503Temporary service issueRetry later with backoff.
Standard error shape
{
  "success": false,
  "code": "validation_error",
  "error": "Invalid destination address format",
  "message": "Invalid destination address format"
}
Pending cap example
{
  "success": false,
  "code": "too_many_pending_swaps",
  "error": "This API key has too many pending swaps. Wait for pending swaps to complete or expire before creating more.",
  "message": "This API key has too many pending swaps. Wait for pending swaps to complete or expire before creating more.",
  "pending_swaps": 100,
  "max_pending_swaps": 100
}
AI Integration
Copy this whole Markdown block into any AI coding tool. It is one self-contained integration handoff: public endpoints, partner authentication, request examples, response fields, status handling, errors, polling rules, and the optional machine-readable schema URL.
AI-ready Markdown
# CryptoSwap API Integration

Build a server-side integration for CryptoSwap. There are two different API surfaces:

1. Public Data API
   - Base URL: https://b1exch.to/api
   - No API key is required.
   - Use only for public display data: rates, liquidity, and public currency metadata.
   - Do not create swaps from public endpoints.

2. Partner API
   - Base URL: https://b1exch.to/api/partner/v1
   - Every request requires an API key, including GET requests.
   - Send the key as either:
     - X-API-Key: b1x_...
     - Authorization: Bearer b1x_...
   - API calls may be sent from clearnet servers or onion hosts when using the matching API hostname supplied by the operator.
   - If the base URL shown here is an .onion URL, clearnet-only servers need the clearnet API hostname before they can call it.
   - Partner portal login is onion-only, but that restriction does not apply to server-to-server API calls.
   - Never expose the API key in frontend JavaScript, mobile apps distributed to users, logs, screenshots, or public repositories.
   - No API key yet? A lifetime partner key can be bought self-serve for $100 in crypto at /buy-api-key on the main site; it is issued automatically once the payment confirms, with no account required.

Optional machine-readable schema:
- https://b1exch.to/api/openapi.json
- Use it only as an additional schema reference. This Markdown is the primary implementation instruction.

Recommended partner integration flow:
1. Verify the key.
   GET /api/partner/v1/me
   Required header: X-API-Key
   Use this to confirm the key works, the partner account is active, scopes are present, commission percent is known, and limits.max_pending_swaps is available.

2. Load partner currencies.
   GET /api/partner/v1/currencies
   Required header: X-API-Key
   Use this to build the swap form. It returns enabled currencies and partner API minimum USD values.

3. Optionally load public display data.
   GET /api/rates
   GET /api/liquidity
   GET /api/currencies
   No API key is required for these endpoints. Use them for UI display only.

4. Preview a quote.
   POST /api/partner/v1/quote
   Required header: X-API-Key
   Body fields:
   - from: source/deposit currency, for example BTC
   - to: destination/output currency, for example LTC
   - amount: source amount the customer is expected to deposit
   - destination: customer payout address for the target currency
   Treat quote responses as indicative only. A quote is not a reservation and does not lock price.

5. Create the live swap.
   POST /api/partner/v1/swaps
   Required header: X-API-Key
   Required body fields:
   - from
   - to
   - amount
   - destination
   - refund_address
   Optional body fields:
   - reference: partner-side order ID, max 100 characters. Use a unique reference per order for retry safety.
   - commission_address: same-chain automatic commission payout address for the source/deposit currency
   Retry behavior: if the same API key repeats POST /swaps with the same reference and identical swap details, return the existing swap instead of creating a duplicate. If the same reference is reused with different details, return HTTP 409 duplicate_reference.
   Store the returned swap ID, deposit address, refund address, destination address, expiry time, and your own reference.

6. Track the swap.
   GET /api/partner/v1/swaps/{id}
   Required header: X-API-Key
   Poll every 20-60 seconds until is_completed is true.

7. Build dashboards or reconciliation tools.
   GET /api/partner/v1/swaps?skip=0&take=50
   GET /api/partner/v1/swaps?status=completed
   Required header: X-API-Key

8. Screen an address for risk before accepting or paying to it (optional).
   GET /api/partner/v1/aml/screen/{address}
   Required header: X-API-Key
   Required scope: aml:read (operators grant it per key).
   Optional query: network (ethereum, bsc, polygon, avalanche, arbitrum, optimism, base) and depth (1-10, default 1).
   The report returns score (0-100) and a band of none/low/medium/high/severe that maps to a suggested action (allow, review, blockPendingReview, block or fileSar). Treat action as advice for your own policy, not an instruction.
   This runs a live multi-source lookup: set your HTTP timeout to at least 180 seconds and call it server-side. A 404 no_screening_data means the address has no history (often a clean, unused address). 429 rate_limited means slow down. 503 service_unavailable is transient, so retry.

9. Delete from partner views only when requested by the partner/user.
   DELETE /api/partner/v1/swaps/{id}
   Required header: X-API-Key
   Treat the swap as permanently removed from partner API and portal views after this call. It does not cancel a live swap.

Example curl calls:

```bash
curl https://b1exch.to/api/partner/v1/me \
  -H "X-API-Key: b1x_your_partner_key"

curl https://b1exch.to/api/partner/v1/currencies \
  -H "X-API-Key: b1x_your_partner_key"

curl -X POST https://b1exch.to/api/partner/v1/quote \
  -H "Content-Type: application/json" \
  -H "X-API-Key: b1x_your_partner_key" \
  -d '{
    "from": "BTC",
    "to": "LTC",
    "amount": 0.01,
    "destination": "ltc1q_customer_destination..."
  }'

curl -X POST https://b1exch.to/api/partner/v1/swaps \
  -H "Content-Type: application/json" \
  -H "X-API-Key: b1x_your_partner_key" \
  -d '{
    "from": "BTC",
    "to": "LTC",
    "amount": 0.01,
    "destination": "ltc1q_customer_destination...",
    "refund_address": "bc1q_customer_refund...",
    "reference": "order-123",
    "commission_address": "bc1q_partner_commission..."
  }'

curl https://b1exch.to/api/partner/v1/swaps/00000000-0000-0000-0000-000000000000 \
  -H "X-API-Key: b1x_your_partner_key"

curl "https://b1exch.to/api/partner/v1/aml/screen/0xADDRESS?network=ethereum" \
  -H "X-API-Key: b1x_your_partner_key"
```

Typical swap response shape:

```json
{
  "success": true,
  "swap": {
    "id": "246fb837-2dcb-4830-8e55-1491ba75be4a",
    "short_id": "246fb837",
    "status": "completed",
    "is_completed": true,
    "outcome": "success",
    "from_currency": "BTC",
    "to_currency": "LTC",
    "deposit_address": "bc1q_customer_deposit...",
    "destination_address": "ltc1q_customer_destination...",
    "refund_address": "bc1q_customer_refund...",
    "amount": 0.01,
    "deposit_amount": 0.01,
    "quoted_output": 1.234567,
    "min_output": 1.209876,
    "output_amount": 1.232100,
    "exchange_rate": 123.4567,
    "service_fee_percent": 1.0,
    "deposit_confirmations": 3,
    "output_confirmations": 1,
    "deposits": [
      {
        "txid": "8c63fc...",
        "currency": "BTC",
        "amount": 0.01,
        "confirmations": 3,
        "address": "bc1q_customer_deposit..."
      }
    ],
    "outputs": [
      {
        "txid": "98b7ad...",
        "currency": "LTC",
        "amount": 1.232100,
        "confirmations": 1,
        "address": "ltc1q_customer_destination..."
      }
    ],
    "reference": "order-123",
    "created_at": "2026-05-15T13:20:00Z",
    "expires_at": "2026-05-15T13:40:00Z",
    "completed_at": "2026-05-15T13:22:11Z",
    "commission_settings": {
      "percent": 2.0,
      "payout_method": "automatic_address",
      "payout_currency": "BTC",
      "payout_address": "bc1q_partner_commission..."
    },
    "commission": {
      "status": "paid",
      "payable": true,
      "payout_method": "automatic_address",
      "amount_usd": 1.27,
      "commission_percent": 2.0,
      "payout_currency": "BTC",
      "payout_address": "bc1q_partner_commission...",
      "payout_txid": "f7b2c1...",
      "created_at": "2026-05-15T13:22:30Z",
      "available_at": "2026-05-15T13:24:10Z",
      "paid_at": "2026-05-15T13:25:02Z"
    }
  }
}
```

Important behavior:
- GET /api/partner/v1/me returns partner, api_key, and limits metadata. Use api_key.scopes and limits.max_pending_swaps to validate setup.
- GET /api/partner/v1/currencies returns enabled currencies, decimal display precision, public minimum amounts, and partner API minimum USD values. Build forms from this instead of hardcoding enabled pairs or precision.
- POST /api/partner/v1/swaps is the live swap creation request. It calculates fresh pricing at creation time. Do not assume POST /quote locks price.
- Use reference as an idempotency key per API key. Same key + same reference + same details returns the existing swap. Same key + same reference + different details returns HTTP 409 with code duplicate_reference.
- refund_address is mandatory for API swap creation.
- commission_address must validate for the source/deposit currency. If omitted, payable commission is held in the partner balance for manual payout.
- Quote responses can include quote_id, from_currency, to_currency, amount, amount_usd, quoted_output, min_output, exchange_rate, service_fee_percent, service_fee_usd, exchange_fee_usd, network_fee, estimated_minutes, expires_in_seconds, binding=false, and note.
- Swap responses can include id, short_id, status, is_completed, outcome, from_currency, to_currency, deposit_address, destination_address, refund_address, amount, deposit_amount, quoted_output, min_output, output_amount, exchange_rate, service_fee_percent, deposit_confirmations, output_confirmations, deposits[], outputs[], refund, reference, created_at, expires_at, completed_at, commission_settings, and commission.
- Fields with no value are returned as null where applicable. deposits[] and outputs[] are always arrays.
- amount is the expected source amount from creation. deposit_amount is the accepted customer deposit amount when known. quoted_output is the creation-time expected output. min_output is the minimum acceptable output (slippage floor); when rate protection is selected it is returned separately as rate_protection_percent. output_amount is the customer payout amount when known.
- exchange_rate is the partner-facing quote rate. service_fee_percent is the partner-facing service fee percent.
- deposits[] is always an array and can contain multiple customer deposits. outputs[] is always an array and can contain one or more customer payout transactions.
- Each deposits[] and outputs[] item can include txid, currency, amount, confirmations, address, and vout when applicable.
- refund is included only when refund data exists and can include txid, amount, currency, address, reason, and refunded_at.
- commission_settings is included on swap responses and shows the commission percent and payout method captured when the swap was created.
- commission returns only the partner-facing result: status, payable flag, payable amount_usd, commission_percent, payout_method, payout_currency, payout_address, payout_txid when paid automatically, reason_code, message, created_at, available_at, and paid_at.
- Internal revenue, cost, margin, and profitability math are not exposed through the partner API.
- Transaction costs for automatic commission payouts are deducted from the partner share.
- There is currently no API endpoint for requesting manual commission payout. Manual payout requests are handled in the Partner Portal.
- The pending swap cap is per API key. If HTTP 429 returns code too_many_pending_swaps, stop creating swaps with that key until pending swaps complete or expire.
- GET /api/partner/v1/aml/screen has its own per-key rate limit. On breach it returns HTTP 429 with code rate_limited (distinct from too_many_pending_swaps); back off and retry.
- Status handling is deliberately simple. Use status plus is_completed instead of depending on internal backend stage names.
- While is_completed is false, keep polling and show the customer a normal in-progress state.
- Public status values are: waiting_for_deposit, processing, completed, expired, refunded, failed.
- When is_completed is true, stop polling and read outcome: success, expired, refunded, or failed.
- Commission status values are: pending, payable, payout_requested, paid, not_payable.
- Commission payout_method values are: partner_balance, automatic_address, manual_payout.
- Partner API application errors use JSON shape: success=false, code, error, and message.
- Always handle JSON errors for HTTP 400, 401, 403, 404, 409, 429, and 503. Invalid JSON can also produce framework validation details, so clients should still fall back to HTTP status and any title/message/error field.
- For 401, send a valid X-API-Key on the current request.
- For 403, the key may be missing a scope or the partner account/key may be suspended.
- For 404, the swap is not visible to this partner/key or the ID is wrong.
- For 409 duplicate_reference, do not create a new order under that reference; reconcile your local order state first.