/ DOCS
HOME DASHBOARD

404.cash API

Swap-as-a-Service. Embed no-KYC crypto exchange on any website.

404.cash lets you embed a fully functional crypto swap widget on your website. Users swap directly — you earn from every trade. 16 exchange engines, 4,600+ coins, zero KYC.

Base URL: https://api.404.cash — All endpoints require authentication via API key.

Quick Start

Get a swap widget running on your site in 3 steps:

1. Create an account

Register at dash.404.cash to get your API key and widget key.

2. Embed the widget

<div id="swap-widget"></div>
<script src="https://swap.404.cash/widget.js"
  data-widget-key="wk_your_key_here"
  data-element="#swap-widget"
  data-theme="dark">
</script>

3. Receive webhooks

Configure a webhook URL in your dashboard to get notified when swaps complete. All webhooks are signed with HMAC-SHA256.

Authentication

All API requests require an X-API-Key header with your merchant API key.

curl -H "X-API-Key: mk_your_api_key_here" \
  https://api.404.cash/v1/merchant/profile

API keys are generated in the dashboard under API Keys. You can create multiple keys and revoke them independently.

Never expose your API key in client-side code. Use it only from your server.

Embed Widget

The swap widget is a self-contained JavaScript bundle hosted at swap.404.cash. It renders inside any container element.

Basic embed

<div id="swap-widget"></div>
<script src="https://swap.404.cash/widget.js"
  data-widget-key="wk_your_key_here"
  data-element="#swap-widget">
</script>

Iframe embed

<iframe
  src="https://swap.404.cash/?key=wk_your_key_here&theme=dark"
  width="420" height="600"
  style="border: none; border-radius: 16px;">
</iframe>

Widget Configuration

Configure your widget via data attributes or query parameters:

ParameterTypeDescription
data-widget-keystringYour widget key (required)
data-themestringdark or light
data-accenthexAccent color, e.g. #00ff41
data-localestringLanguage: en, zh-TW, ru, es, ar, pt, ja, ko, fr, de
data-fromstringDefault "from" ticker, e.g. btc
data-tostringDefault "to" ticker, e.g. xmr
data-ghostbooleanEnable Ghost Mode (XMR privacy routing) PRO
data-provider-linkbooleanShow provider link on trade page

Bring Your Own Keys (BYOK)

Pro and Max merchants can use their own exchange API keys for direct provider access, better rates, and higher limits.

EngineRequired KeysPlan
ChangeNowapi_keyPRO
Exolixapi_keyPRO
StealthExapi_keyPRO
Wagyuapi_key, secret, priv_api_keyPRO
LetsExchangeapi_keyPRO
Swaptobeapi_keyPRO
XChangeapi_keyPRO
Houdiniapi_keyPRO
PegasusSwapapi_keyPRO
Lizexapi_keyPRO
SageSwapapi_keyPRO

Configure BYOK keys in the dashboard under Widget Settings. Keys are transmitted via internal service bindings — never exposed publicly.

With BYOK, you earn the provider's rates directly. 404.cash only takes the platform fee (0.15% Pro / 0.08% Max).

Merchant Profile

GET /v1/merchant/profile

Get your merchant profile, plan, quota balance, and referral info.

{
  "id": "mc_abc123",
  "name": "My Project",
  "email": "me@example.com",
  "plan": "pro",
  "quota_balance_usd": 42.50,
  "referral_code": "ref_xyz",
  "webhook_url": "https://example.com/webhook",
  "created_at": 1711900000
}

Widgets

POST /v1/widgets

Create a new swap widget. Returns the widget key for embedding.

{
  "widget_key": "wk_abc123def456"
}
GET /v1/widgets

List all your widgets with their configuration.

{
  "widgets": [
    {
      "id": "wk_abc123",
      "label": "Main Widget",
      "theme": "dark",
      "from_tickers": ["btc", "eth"],
      "to_tickers": ["xmr"],
      "created_at": 1711900000
    }
  ]
}
PUT /v1/widgets/:id

Update a widget's theme, allowed tickers, label, accent color, locale, and other settings.

{
  "ok": true
}

Swaps

GET /v1/swaps

List swaps for your merchant account. Supports limit, offset, status, and widget_id query params.

{
  "swaps": [
    {
      "id": "sw_abc123",
      "from_ticker": "btc",
      "to_ticker": "xmr",
      "amount_from": 0.01,
      "status": "finished",
      "engine": "changenow",
      "widget_id": "wk_abc123",
      "created_at": 1711900000
    }
  ],
  "total": 1
}
GET /v1/swaps/stats/summary

Get aggregated swap statistics: totals, last 24h, and breakdown by status.

{
  "total": { "swaps": 150, "volume_usd": 12500.00 },
  "last_24h": { "swaps": 5, "volume_usd": 420.00 },
  "by_status": [
    { "status": "finished", "count": 120 },
    { "status": "pending", "count": 15 },
    { "status": "failed", "count": 10 },
    { "status": "expired", "count": 5 }
  ]
}

Quota & Billing

POST /v1/quota/deposit

Create a quota top-up deposit. Pay with USDT on Tron, ETH, BSC, or Polygon to add balance.

{
  "deposit_id": "dep_abc123",
  "amount_usd": 10.00,
  "pay_address": "TXyz...abc",
  "pay_amount": 10.00,
  "chain": "tron",
  "currency": "USDT",
  "status": "pending",
  "expires_at": 1711986400
}
GET /v1/quota/pricing

Get current quota pricing and available payment chains.

{
  "per_swap_usd": 0.10,
  "min_deposit_usd": 5,
  "chains": ["tron", "bsc", "polygon"]
}

Webhook Test

POST /v1/merchant/webhook-test

Send a test webhook payload to your configured URL. Useful for verifying your endpoint before going live.

{
  "ok": true
}

Webhook Events

When a swap changes status, 404.cash sends a POST request to your configured webhook URL with the following payload:

{
  "event": "swap.status_changed",
  "swap": {
    "id": "sw_abc123",
    "status": "finished",
    "from_ticker": "btc",
    "to_ticker": "xmr",
    "amount_from": 0.01,
    "widget_id": "wk_abc123",
    "created_at": 1711900000
  }
}

Event types

EventDescription
swap.status_changedFired when a swap transitions to a new status (pending, confirming, exchanging, sending, finished, failed, expired, refunded)

Webhook Verification

All webhooks include an X-Webhook-Signature header containing an HMAC-SHA256 signature of the raw request body, signed with your webhook secret.

Webhook verification is mandatory. Requests without a valid signature must be rejected.
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(body)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

// Express example
app.post('/webhook', (req, res) => {
  const sig = req.headers['x-webhook-signature'];
  const raw = JSON.stringify(req.body);

  if (!verifyWebhook(raw, sig, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }

  const { event, swap } = req.body;
  console.log(`Swap ${swap.id} → ${swap.status}`);
  res.status(200).send('OK');
});

Plans & Rate Limits

Free

$0
10 free swaps included
  • 1 widget
  • 6 default coins
  • 60 req/min
  • Standard support

Pro PRO

$200
0.15% platform fee per swap
  • 5 widgets
  • 4,600+ coins
  • 300 req/min
  • BYOK support
  • Ghost Mode
  • Webhooks

Max MAX

$1,000
0.08% platform fee per swap
  • Unlimited widgets
  • 4,600+ coins
  • 1000 req/min
  • BYOK support
  • Ghost Mode
  • White-label
  • Custom domain
  • Priority support

Plans can also be unlocked by volume: $500K total for Pro, $5M total for Max (auto-upgrade).

Error Codes

All errors return a JSON object with an error field:

{
  "error": "Invalid API key"
}
HTTP StatusMeaning
400Bad request — missing or invalid parameters
401Unauthorized — missing or invalid API key
403Forbidden — feature not available on your plan
404Resource not found
429Rate limited — too many requests
500Internal server error
503Service unavailable — upstream provider down

Swap Statuses

StatusDescription
waitingAwaiting user deposit
confirmingDeposit received, awaiting confirmations
exchangingSwap in progress at the exchange engine
sendingSending output to destination address
finishedSwap completed successfully
failedSwap failed — check provider for details
expiredNo deposit received within timeout
refundedDeposit returned to sender

404.cash — Swap as a Service — Dashboard