Documentation

Integrate Float.

Float is an aggregator for the Canton Network. One integration gives your users a route from 2,000+ assets into CC, and back out again, quoted across six swap partners. No account is needed to read these docs or to call the API; an API key attributes orders to you, raises your rate limits and enables Idempotency-Key.

Integrate with AI

Prompt copied

Paste it into Claude Code, Cursor, Copilot… from your project's root. Your assistant reads Float's docs, asks for your website or brand kit, then builds Float into your app in your branding.

  1. Have your API key (for your own screen built on the API) or your referral code (for the embedded widget) handy — the assistant first asks which way you want to integrate, then asks for the one it needs. Don't paste a key into the prompt.
  2. Paste the prompt into your AI assistant, opened at your project's root.
  3. Answer its questions — your website or brand kit first — and review what it builds.
Prompt
You are integrating Float (https://www.myfloat.cc) into my product. Float swaps Canton Coin (CC)
to and from ~2,000 assets at the best rate across its liquidity partners, and I earn 0.2% of the
CC side of every order opened with my API key or my referral code.

Step 1. Read these first, completely, and treat them as the source of truth for every endpoint,
field, state and error code:
  - https://www.myfloat.cc/docs/api.md   (the API reference)
  - https://www.myfloat.cc/openapi.json  (OpenAPI 3.1 spec)
  - https://www.myfloat.cc/docs/ai.md    (the reference widget spec and starter code)
  - https://www.myfloat.cc/llms.txt      (index of Float's docs, with the key facts)
  - https://www.myfloat.cc/downloads/float-widget-starter.zip  (the Next.js starter to adapt)

Step 2. Before writing any code, ask me these questions, ONE AT A TIME, and wait for each answer:
  1. Integration type: "How do you want to integrate Float?
       (A) API — your own swap screen in your app, built on Float's API with your API key: full
           control of the look and flow; needs a small server-side proxy.
       (B) Widget — Float's ready-made swap screen embedded on your page with your referral code:
           no API key, no backend, live in minutes."
     My answer decides everything below. If I am unsure, explain the trade-off in two lines and
     recommend (A) when my app has a backend, (B) for a static site or no-code.
  2. Branding: "What's your website URL or brand kit (logo, colours, fonts)?"
     Use it to match my branding: read my site's colours and fonts (or the kit) and set them
     as CSS variables — for (A) the whole widget, for (B) the section, heading and buttons around
     the embed (Float's screen inside the iframe keeps Float's own look).
  3. For (A) — API key: "Paste your Float API key from the partner dashboard."
     Store it ONLY in a server-side environment variable named FLOAT_API_KEY (.env.local or my
     host's secret store). Never put it in client code, a NEXT_PUBLIC_/VITE_ variable, a URL,
     logs, or the repository. Add .env* to .gitignore if needed.
     For (B) — referral code: "Paste your Float referral code (partner dashboard → Referral
     links)." It is public and safe in client code; never ask me for an API key in (B).
  4. Ideas (optional, I may skip): "Any ideas for how you want Float in your product?"
  5. Placement: "Where in your app should it live?" (a page, a modal, a tab…), or I describe it.

Step 3, if I chose (A) API. Build the integration end to end:
  - Set up the repo or app structure as needed for my stack.
  - A small server-side proxy route that holds FLOAT_API_KEY and calls Float's /v1 API
    (base https://api.myfloat.cc/v1): GET /assets, POST /quote,
    POST /order (with an Idempotency-Key per intended order), GET /order/{claimToken},
    POST /order/{claimToken}/refund-address. Allowlist exactly these paths. The browser only
    ever calls my proxy — Float's API is server-side only and does not allow browser calls
    from my domain.
  - The UI, following the REFERENCE WIDGET spec on https://www.myfloat.cc/docs/ai.md exactly
    (two tabs Get CC / Withdraw CC, token picker, live quote and routes, Exchange, deposit step
    with countdown and QR, status tracking, every state and error message), in my branding,
    usable at 375 px wide and with the keyboard.
  - A webhook receiver in my backend (e.g. POST /api/float-webhook) that verifies the
    Float-Signature header (t=…,v1=…: HMAC-SHA256 with the endpoint secret over "<t>.<raw body>",
    constant-time compare, accept either v1 during a rotation, reject t older than 5 minutes) on
    the RAW body before parsing, de-duplicates on the event id, answers 2xx within 10 s, and
    handles order.state_changed (data.order is the public order object), payout.updated and
    webhook.test. Register it with my key via POST /v1/webhooks once the app is deployed on a
    public https URL; store the returned secret (shown once) as the server-side env var
    FLOAT_WEBHOOK_SECRET; then send a test event with POST /v1/webhooks/{id}/test. The widget
    still polls GET /order/{claimToken} for the order on screen (every 10–30 s, 5 s while
    state is preparing_deposit_address) and stops at a final state.
  - Tests, or a manual test checklist, and a README (how to run, where the key goes).

Step 3, if I chose (B) Widget. Build the embed exactly as section "10. Embed widget" of
https://www.myfloat.cc/docs/api.md describes:
  - The iframe https://www.myfloat.cc/bridge?embed=1&ref=<my referral code>, plus dir / asset /
    amount when my placement calls for it (e.g. a "Withdraw CC" entry point → dir=out). Give it
    a title, width 100%, no border, loading="lazy".
  - The height listener, accepting messages only when e.origin === "https://www.myfloat.cc"
    exactly and e.data.source === "float-widget", so the iframe never scrolls inside my page.
  - A section in my branding around it at my chosen placement, usable at 375 px wide, plus a
    plain referral link (https://www.myfloat.cc/bridge?ref=<code>) as a fallback button.
  - No API key, no proxy and no webhook: orders are attributed by the referral code and I see
    them and my earnings in the partner dashboard.

Step 4. Check it and hand over. For (A): run it, load the asset list and a live quote through
the proxy (no real order), check 375 px and keyboard use, then tell me what you built, which env
vars to set on my host, and how to register the webhook once the app is deployed. For (B): load
the page, check the embed shows, resizes with its content and works at 375 px, then tell me what
you built and where.

Rules:
  - Use rateType "float" by default.
  - Amounts are decimal strings: never do money arithmetic in floating point; show amountIn
    exactly as returned; round received amounts down for display.
  - Render the API's error sentence as text, never as HTML (no innerHTML); build UI from data
    with textContent / your framework's text binding.
  - Identify an asset by symbol + network (the pair), never by a ticker suffix like "-SOL". Omit
    network (do not send null) when the asset row has none.
  - Withdraw CC (CC → X): the user sends exactly amountIn CC to depositAddress — no memo, ever.
    The PAYOUT side may need a destination tag / memo: when the asset row or the quote says
    destinationExtraIdNeeded, show the field (label: destinationExtraIdName) with the warning
    "Sending to an exchange? Add your destination tag/memo, or the funds may be lost." and send
    it as destinationExtraId on the quote and the order.
    Get CC (X → CC): if depositExtraId is not null, the user must include it as the memo/tag.
  - Never create a real order while testing unless I say so; quotes and the asset list are safe.
  - If the docs and the spec ever disagree with what the API returns, trust the API and tell me.

You may start from Float's starter (Next.js App Router), printed in full on
https://www.myfloat.cc/docs/ai.md and downloadable from
https://www.myfloat.cc/downloads/float-widget-starter.zip — adapt it to my stack and branding.
Copies a ready-made prompt for Claude Code, Cursor or Copilot: it reads these docs, asks for your brand, and builds Float into your app.

Base URL — every path below is relative to it:

https://api.myfloat.cc/v1

The older unversioned paths under /api/float still work, but new integrations should use /v1.

Full API reference →Every field, state and error, with examples in curl, Node and Python.Integrate with your AI →A copy-paste prompt, the widget spec and a Next.js starter.

Machine-readable: OpenAPI 3.1 spec · reference as Markdown · llms.txt.

Endpoints

Six calls for orders, plus webhooks and the spec. Every request and response is JSON. Register a webhook (POST /v1/webhooks, with your key) to receive order.state_changed events signed with Float-Signature, or poll GET /v1/order/{claimToken} every 10–30 seconds while the user is watching — see the full reference.

GET /v1/assets?q=&limit=&offset=&network=Search the assets Float can swap. limit is 1–200 (default 50); network filters by chain; ?all=1 returns every row with only symbol, name, network, networkName, icon, networkIcon and, where a payout needs a tag or memo, destinationExtraIdNeeded / destinationExtraIdName. Identify an asset by symbol + network, not by a ticker suffix.
POST /v1/quoteAn indicative price across every venue — the winner plus alternatives. Binds nothing: there is no quote id, and the order re-quotes.
POST /v1/orderOpens the order and returns where the user sends. Moves no money — the user sends the deposit from their own wallet.
GET /v1/order/{claimToken}Read the order (refreshed from its venue). The token comes back from POST /v1/order and needs no account.
POST /v1/order/{claimToken}/refund-address{ address, acceptOut? } — on an asset → CC order, the user's source-chain refund address (opens an order that was waiting for one); on CC → asset, the user's Canton refund party.
GET /v1/r/{code}Resolve a referral code → { ref, partner }. Counts a click.
POST /v1/webhooks (+ GET, PATCH, DELETE, /test, /rotate-secret, /deliveries)Register and manage webhook endpoints with your API key. Events: order.state_changed, payout.updated, webhook.test, signed with Float-Signature (HMAC-SHA256).
GET /v1/openapi.jsonThis API as OpenAPI 3.1 (a copy is at www.myfloat.cc/openapi.json). The API host's root /openapi.json is a different product — Slay's wallet API.
Rather have your AI assistant build it?
Integrate with AI

Prompt copied

Paste it into Claude Code, Cursor, Copilot… from your project's root. Your assistant reads Float's docs, asks for your website or brand kit, then builds Float into your app in your branding.

  1. Have your API key (for your own screen built on the API) or your referral code (for the embedded widget) handy — the assistant first asks which way you want to integrate, then asks for the one it needs. Don't paste a key into the prompt.
  2. Paste the prompt into your AI assistant, opened at your project's root.
  3. Answer its questions — your website or brand kit first — and review what it builds.
Prompt
You are integrating Float (https://www.myfloat.cc) into my product. Float swaps Canton Coin (CC)
to and from ~2,000 assets at the best rate across its liquidity partners, and I earn 0.2% of the
CC side of every order opened with my API key or my referral code.

Step 1. Read these first, completely, and treat them as the source of truth for every endpoint,
field, state and error code:
  - https://www.myfloat.cc/docs/api.md   (the API reference)
  - https://www.myfloat.cc/openapi.json  (OpenAPI 3.1 spec)
  - https://www.myfloat.cc/docs/ai.md    (the reference widget spec and starter code)
  - https://www.myfloat.cc/llms.txt      (index of Float's docs, with the key facts)
  - https://www.myfloat.cc/downloads/float-widget-starter.zip  (the Next.js starter to adapt)

Step 2. Before writing any code, ask me these questions, ONE AT A TIME, and wait for each answer:
  1. Integration type: "How do you want to integrate Float?
       (A) API — your own swap screen in your app, built on Float's API with your API key: full
           control of the look and flow; needs a small server-side proxy.
       (B) Widget — Float's ready-made swap screen embedded on your page with your referral code:
           no API key, no backend, live in minutes."
     My answer decides everything below. If I am unsure, explain the trade-off in two lines and
     recommend (A) when my app has a backend, (B) for a static site or no-code.
  2. Branding: "What's your website URL or brand kit (logo, colours, fonts)?"
     Use it to match my branding: read my site's colours and fonts (or the kit) and set them
     as CSS variables — for (A) the whole widget, for (B) the section, heading and buttons around
     the embed (Float's screen inside the iframe keeps Float's own look).
  3. For (A) — API key: "Paste your Float API key from the partner dashboard."
     Store it ONLY in a server-side environment variable named FLOAT_API_KEY (.env.local or my
     host's secret store). Never put it in client code, a NEXT_PUBLIC_/VITE_ variable, a URL,
     logs, or the repository. Add .env* to .gitignore if needed.
     For (B) — referral code: "Paste your Float referral code (partner dashboard → Referral
     links)." It is public and safe in client code; never ask me for an API key in (B).
  4. Ideas (optional, I may skip): "Any ideas for how you want Float in your product?"
  5. Placement: "Where in your app should it live?" (a page, a modal, a tab…), or I describe it.

Step 3, if I chose (A) API. Build the integration end to end:
  - Set up the repo or app structure as needed for my stack.
  - A small server-side proxy route that holds FLOAT_API_KEY and calls Float's /v1 API
    (base https://api.myfloat.cc/v1): GET /assets, POST /quote,
    POST /order (with an Idempotency-Key per intended order), GET /order/{claimToken},
    POST /order/{claimToken}/refund-address. Allowlist exactly these paths. The browser only
    ever calls my proxy — Float's API is server-side only and does not allow browser calls
    from my domain.
  - The UI, following the REFERENCE WIDGET spec on https://www.myfloat.cc/docs/ai.md exactly
    (two tabs Get CC / Withdraw CC, token picker, live quote and routes, Exchange, deposit step
    with countdown and QR, status tracking, every state and error message), in my branding,
    usable at 375 px wide and with the keyboard.
  - A webhook receiver in my backend (e.g. POST /api/float-webhook) that verifies the
    Float-Signature header (t=…,v1=…: HMAC-SHA256 with the endpoint secret over "<t>.<raw body>",
    constant-time compare, accept either v1 during a rotation, reject t older than 5 minutes) on
    the RAW body before parsing, de-duplicates on the event id, answers 2xx within 10 s, and
    handles order.state_changed (data.order is the public order object), payout.updated and
    webhook.test. Register it with my key via POST /v1/webhooks once the app is deployed on a
    public https URL; store the returned secret (shown once) as the server-side env var
    FLOAT_WEBHOOK_SECRET; then send a test event with POST /v1/webhooks/{id}/test. The widget
    still polls GET /order/{claimToken} for the order on screen (every 10–30 s, 5 s while
    state is preparing_deposit_address) and stops at a final state.
  - Tests, or a manual test checklist, and a README (how to run, where the key goes).

Step 3, if I chose (B) Widget. Build the embed exactly as section "10. Embed widget" of
https://www.myfloat.cc/docs/api.md describes:
  - The iframe https://www.myfloat.cc/bridge?embed=1&ref=<my referral code>, plus dir / asset /
    amount when my placement calls for it (e.g. a "Withdraw CC" entry point → dir=out). Give it
    a title, width 100%, no border, loading="lazy".
  - The height listener, accepting messages only when e.origin === "https://www.myfloat.cc"
    exactly and e.data.source === "float-widget", so the iframe never scrolls inside my page.
  - A section in my branding around it at my chosen placement, usable at 375 px wide, plus a
    plain referral link (https://www.myfloat.cc/bridge?ref=<code>) as a fallback button.
  - No API key, no proxy and no webhook: orders are attributed by the referral code and I see
    them and my earnings in the partner dashboard.

Step 4. Check it and hand over. For (A): run it, load the asset list and a live quote through
the proxy (no real order), check 375 px and keyboard use, then tell me what you built, which env
vars to set on my host, and how to register the webhook once the app is deployed. For (B): load
the page, check the embed shows, resizes with its content and works at 375 px, then tell me what
you built and where.

Rules:
  - Use rateType "float" by default.
  - Amounts are decimal strings: never do money arithmetic in floating point; show amountIn
    exactly as returned; round received amounts down for display.
  - Render the API's error sentence as text, never as HTML (no innerHTML); build UI from data
    with textContent / your framework's text binding.
  - Identify an asset by symbol + network (the pair), never by a ticker suffix like "-SOL". Omit
    network (do not send null) when the asset row has none.
  - Withdraw CC (CC → X): the user sends exactly amountIn CC to depositAddress — no memo, ever.
    The PAYOUT side may need a destination tag / memo: when the asset row or the quote says
    destinationExtraIdNeeded, show the field (label: destinationExtraIdName) with the warning
    "Sending to an exchange? Add your destination tag/memo, or the funds may be lost." and send
    it as destinationExtraId on the quote and the order.
    Get CC (X → CC): if depositExtraId is not null, the user must include it as the memo/tag.
  - Never create a real order while testing unless I say so; quotes and the asset list are safe.
  - If the docs and the spec ever disagree with what the API returns, trust the API and tell me.

You may start from Float's starter (Next.js App Router), printed in full on
https://www.myfloat.cc/docs/ai.md and downloadable from
https://www.myfloat.cc/downloads/float-widget-starter.zip — adapt it to my stack and branding.

Create an order

Quote first with the same body (minus destination) at POST /v1/quote, show the user amountOut and the alternatives, then open the order. Pass venue to execute at the route the user picked; it is refused, never swapped, if that venue is no longer quoting.

http
POST https://api.myfloat.cc/v1/order
Content-Type: application/json
Authorization: Bearer fl_live_…          # optional; from your server only
Idempotency-Key: 6f1c0d7e-4b8a-4f0e-…    # optional; needs the key

{
  "direction":     "in",                   # "in" = asset → CC, "out" = CC → asset
  "from":          "USDT",                 # the asset sent, on "in" ("to" on "out")
  "network":       "TRON",                 # optional: chain of the non-CC asset; omit (not null) for the default
  "amount":        "100",                  # "in": amount of "from"; "out": amount of CC
  "destination":   "yourname::1220e8c7…",  # "in": Canton party ID; "out": address on that chain
  "rateType":      "float",                # recommended; the default is "fixed", which priced ~1.7% worse live
  "refundAddress": "TXyz…"                 # optional, "in": the user's source-chain refund address
}

# On "out": "to" instead of "from", and optionally "refundParty":
# the user's own Canton party, where Float returns their CC if the swap
# cannot complete. Ask for it whenever the user may send from an exchange.
# Without a key, "ref": "YOUR_CODE" attributes the order to you.

The 201 response is the order. Tell the user to send exactly amountIn of from to depositAddress, with depositExtraId as the memo or tag when it is not null, before depositDeadline (ISO — show it as a countdown computed from this field). When the user pays Float, a payment that lands before depositGraceUntil (10 minutes later) is still processed; after that, with nothing received, the order expires and anything sent later is refunded automatically. deadline is the same instant in Unix ms, kept for compatibility. On CC → asset, depositAddress is a Canton party used by this order alone (no memo): the user sends exactly amountIn CC to it from their Canton wallet. Less than that is refunded and the order cancelled; more goes ahead and the extra is refunded. On asset → CC, depositAddress is the venue's address on the source chain and depositGraceUntil is null.

claimToken
The order's handle and a bearer capability: whoever holds it can read the order. Store it — it is how you, or your user, read the order later.
Refund address
When a quote says needsRefundAddress: true and you send none, the order comes back as awaiting_refund_address with an empty depositAddress. POST /refund-address opens it; unanswered, it expires after 24 hours.

Order state

Drive your UI from state — one field, ten values, four of them final. status and custodialState are internal and kept only for compatibility; do not branch on them.

text
[awaiting_refund_address | preparing_deposit_address →]
  awaiting_deposit → confirming → exchanging → sending → completed
                                       ↘ failed | refunded | expired
awaiting_refund_addressAsset → CC only. The route needs the user's source-chain refund address before the venue order opens. No deposit address yet — add one with /refund-address.
preparing_deposit_addressCC → asset only. Float is creating this order's own deposit address; depositAddress is "". Keep polling.
awaiting_depositWaiting for the user's deposit.
confirmingThe deposit was seen and is being confirmed or forwarded.
exchangingThe venue is swapping.
sendingThe payout to the user is on its way.
completedThe user has been paid. Final.
refundedThe deposit went back. Final.
failedThe swap will not complete. Final — except that when Float is returning a deposit it holds, it moves on to refunded.
expiredThe deposit window closed with nothing received. Final.

Some in-progress states come from the venue's own status, read live on each GET, so treat them as progress and only the final states as facts.

Networks

Many assets live on several chains. network on /quote and /order names the chain of the non-CC asset; CC is always on Canton. Any common spelling is accepted and answered with Float's code: BITCOIN (BTC), ETHEREUM (ETH, ERC20), TRON (TRX, TRC20), BSC (BEP20, BNB), SOLANA (SOL), POLYGON, ARBITRUM, BASE and more.

With network, only quotes on that chain are considered — a different chain is never substituted, because a deposit on the wrong chain is lost. Without it, an asset Float pins to a chain (USDC and ETH → Ethereum, USDT → Tron, BTC, SOL and other coins on their own chain…) is quoted on that chain at every venue (networkChoice: "float_default"); any other asset uses each venue's own default chain, which can differ between venues (networkChoice: "venue_default"). The response always says which (network). If the chain matters, send it.

Idempotency

A timeout on POST /v1/order does not tell you whether an order opened. Send an Idempotency-Key (a UUID per intended order) and retry with the identical body: you get the same order back, 201 with Idempotent-Replayed: true, and no second order is opened. A different body with the same key is 409 idempotency_key_reused; a retry while the first is still opening is 409 idempotency_in_progress with Retry-After. Keys need an API key, are remembered per partner for 24 hours, and a request that fails frees its key.

Errors

Every error is { "error": "<sentence>", "code": "<stable code>" }. The sentence is for a person and may be reworded; branch on code. Render it as text, never as HTML (no innerHTML).

400 invalid_requestMissing or bad field: no asset, amount ≤ 0, bad network, destination, refundAddress or refundParty.
400 venue_refusedThe venue rejected the order; its message is included.
400 idempotency_key_invalidIdempotency-Key is not 1–255 visible ASCII characters.
400 idempotency_requires_keyIdempotency-Key was sent without an API key.
401 invalid_keyThe key is unknown, revoked, or used from an IP it does not allow.
404 not_foundUnknown claim token, referral code or path.
409 conflictNo route at this size, the chosen venue is not quoting it, or the order is already finished.
409 venue_unavailablePOST /order: the venue that quoted this route would not open it. Body also has venue (its id). Nothing was opened — retry with another venue from alternatives, or re-quote.
409 requote_neededA refund address would open the order more than 0.5% worse. Body has requote { venue, previousOut, freshOut }; resend with acceptOut.
409 idempotency_key_reusedSame Idempotency-Key, different body.
409 idempotency_in_progressThe first request with this key is still opening the order. Retry after Retry-After.
422 unprocessableThe Canton party cannot receive CC yet (no transfer preapproval).
429 rate_limitedOver the limit. Wait Retry-After seconds.
502 upstream_errorA venue did not answer. Re-quote; with an Idempotency-Key, retry the same request.
503 unavailableFloat is switched off, deposits are paused, every deposit address is in use, or a component is temporarily unavailable. Nothing was opened — retry later.

Rate limits

With an API key
Per key, per minute: 60 POST /quote, 20 POST /order (and /refund-address), 300 other requests. Every keyed response carries X-RateLimit-Limit, -Remaining and -Reset.
Without a key
12 requests a minute per IP address, approximate (counted per edge instance) — a server without a key shares that budget across all its users. Over either limit: 429 rate_limited with Retry-After in seconds.

Embed widget

Put Float's swap screen inside your page with an iframe and your referral code — never an API key. Orders placed in it are attributed to you through ref, and each visit counts a click on that link.

html
<iframe src="https://www.myfloat.cc/bridge?embed=1&ref=YOUR_CODE"
        style="width:100%;border:0" title="Swap to CC"></iframe>
<script>
  addEventListener("message", (e) => {
    if (e.origin === "https://www.myfloat.cc" && e.data?.source === "float-widget" && e.data.type === "height")
      document.querySelector("iframe[title='Swap to CC']").style.height = e.data.height + "px";
  });
</script>

Use www.myfloat.cc exactly — the bare domain redirects there, so that is the origin the messages come from. Besides height, the widget posts direction (in or out), order_created (the direction only) and order_state. The widget never posts the order's claim token — no secrets, no addresses, nothing that can act on an order. Optional parameters: dir (in or out), asset, amount (default 250 USDT on Get CC, 500 CC on Withdraw CC), and order (a claim token, to reopen that order's status screen). Details: Messages from the widget. A plain referral link is the same page without embed=1: https://www.myfloat.cc/bridge?ref=YOUR_CODE .

Affiliate program

Every order created with your API key or referral code earns 0.2% of the swap's CC amount — the CC the venue delivers on an asset → CC swap, the CC the user sends on CC → asset — paid in CC and withdrawable once the order completes. It comes out of Float's own fee, so your user gets exactly the price they would get on myfloat.cc. Orders that fail, are refunded or expire earn nothing.

Attribution is fixed when the order opens: your API key if the request carries a valid one, otherwise the referral code. Withdraw from the dashboard; payouts are sent in CC to the payout party you set in Settings, which must be able to receive CC (a transfer preapproval).

API keys

1. Keys are server-only. Send them as Authorization: Bearer fl_live_… from your backend — never in a web page, an app bundle or a URL. A key is only ever read from that header.
2. Call the API from your server. It is built for server-to-server use, and calling it from a web page on your own domain is not supported (CORS blocks it) — put a small proxy route on your backend, or use the embed widget.
3. Create as many keys as you need, and bind each to your server IPs for extra safety. On /v1 a key that is unknown, revoked or used from another IP is refused with 401 invalid_key.
4. Keys are shown once, at creation; only a hash is stored. Lost one? Revoke it and create another.
Create account / Log inContact support