# LandedFX > LandedFX is an FX routing API. It prices what actually lands when money moves between 25 local currencies and any stablecoin, across P2P venues, payment rails, chains and swap providers, at your exact size. It also prices naira rate locks and carry, and builds non-custodial deposits into the Carry vault on Base. - API base URL: https://api.landedfx.com/api/v1 - OpenAPI spec: https://api.landedfx.com/openapi.json - MCP server (Streamable HTTP): https://api.landedfx.com/mcp - Auth: optional `x-api-key` header. Most endpoints work without a key; `POST /quotes` needs one. Get a free key (5,000 calls a month) with `POST /api/v1/keys`. # Introduction Source: https://docs.landedfx.com The landed price of money. One API call for what moving between a local currency and a stablecoin really costs, at your size. A rate aggregator tells you the headline price of a dollar. LandedFX tells you what **you** get, after every cost, at **your** order size, over **your** payment rail, and the route that gets you there. ```json title="KES 150,000 via M-Pesa → USDC on Base (a live quote)" { "amountOut": "1151.07", "idealAmountOut": "1158.32", "allInBps": 62.6, "route": { "summary": "Buy USDT on Binance P2P → Withdraw on BNB Chain → Swap via NEAR Intents" }, "confidence": { "level": "high" } } ``` ## What a quote prices - [Local currency ↔ USDT](/concepts/rails): Live P2P ads on Bybit and Binance in 25 currencies, filtered by your order size, merchant reputation and payment rail. - [Counterparty screening](/concepts/screening): An AI model reads each candidate ad's terms in any language and drops scam patterns. - [Leaving the venue](/concepts/routing): Live withdrawal fees per network. Binance charges 2 USDT on Tron and 0.01 on BNB Chain. - [USDT ↔ any chain](/guides/executable-swaps): The best of Relay and NEAR Intents, gas included, executable from your own wallet. ## Four kinds of transfer | From | To | Example | What happens | |---|---|---|---| | Local currency | Stablecoin | `KES:mpesa` → `USDC:base` | Buy USDT over P2P, withdraw on the cheapest network, swap | | Stablecoin | Local currency | `USDC:base` → `NGN:bank` | Swap into USDT on a network, deposit, sell over P2P | | Local currency | Local currency | `KES:mpesa` → `NGN` | Buy and sell on one venue, or move between venues | | Stablecoin | Stablecoin | `USDT:tron` → `USDC:base` | Best of Relay and NEAR Intents | > **Priced, not executed** P2P legs are priced, not executed: settling them needs an account with the venue. Swap legs can be executed from your own wallet. LandedFX never holds or moves funds. Start with the [Quickstart](/quickstart). # Quickstart Source: https://docs.landedfx.com/quickstart Get a key, price your first route, and read the result. ### Get an API key Get a free key on [landedfx.com](https://landedfx.com/#partners), or straight from the API: ```bash curl -X POST https://api.landedfx.com/api/v1/keys \ -H "content-type: application/json" \ -d '{ "name": "Ada Obi", "email": "ada@acme.com" }' ``` The key is shown once. Send it as the `x-api-key` header. Using an AI coding tool? [Connect the MCP server](/guides/ai-tools) and it can do this for you. ### Quote a transfer **cURL** ```bash curl -X POST https://api.landedfx.com/api/v1/quotes \ -H "x-api-key: $LANDEDFX_KEY" \ -H "content-type: application/json" \ -d '{ "from": "KES:mpesa", "to": "USDC:base", "amount": "150000" }' ``` **TypeScript** ```ts const res = await fetch('https://api.landedfx.com/api/v1/quotes', { method: 'POST', headers: { 'x-api-key': process.env.LANDEDFX_KEY!, 'content-type': 'application/json' }, body: JSON.stringify({ from: 'KES:mpesa', to: 'USDC:base', amount: '150000' }), }); const { data: quote } = await res.json(); ``` **Python** ```python import os, requests quote = requests.post( "https://api.landedfx.com/api/v1/quotes", headers={"x-api-key": os.environ["LANDEDFX_KEY"]}, json={"from": "KES:mpesa", "to": "USDC:base", "amount": "150000"}, ).json()["data"] ``` ### Read the result | Field | Meaning | |---|---| | `amountOut` | What lands, in the `to` asset | | `idealAmountOut` | What the amount would buy at mid-market with nothing charged | | `allInBps` | Total cost against mid-market, in basis points (62.6 bps = 0.626%) | | `route.steps` | Each leg, with its own cost and whether it's executable | | `alternatives` | Up to four next-best routes | | `confidence` | `high`, `medium` or `low`, with reasons | ### Act on it Quotes expire after 60 seconds (`expiresAt`). Re-quote before you execute. Swap legs can be executed through [`POST /swap/quotes`](/guides/executable-swaps). # Authentication & errors Source: https://docs.landedfx.com/authentication API keys, rate limits, the response envelope and error handling. ## API keys Keys look like `lfx_live_` followed by 32 characters. Send yours in the `x-api-key` header (or `Authorization: Bearer `). ```bash curl https://api.landedfx.com/api/v1/usage -H "x-api-key: $LANDEDFX_KEY" ``` Endpoints that do work for you need a key: quotes, swap quotes, rate locks and carry quotes. Market data is public without one, at a lower rate limit. A key that is sent but not valid is always rejected, even on public endpoints, so a typo never fails silently. We store only a hash of your key, so it is shown once, when it is issued. If you lose it, ask for a new one and we revoke the old one. Never ship a key to a browser or mobile app. Call LandedFX from your server and pass results to the client. ## Plans and limits | Plan | Price for 30 days | Requests per minute | Calls per month | |---|---|---|---| | Free | $0 | 60 | 5,000 per key | | Growth | $99 | 300 | 250,000 across your account | | Scale | $499 | 1,200 | 2,000,000 across your account | | Without a key | | 30 per IP | Public endpoints only | Need more than Scale? Email hello@landedfx.com. Upgrade under [Plan and billing](https://app.landedfx.com/billing) in the dashboard. You pay in USDC on Base from your wallet, and the plan applies to all your keys within a minute. Payments don't renew by themselves: we email you 7 days and 1 day before a plan ends, and your keys keep their limits for 3 more days before moving to Free. Moving up credits the unused part of your current plan. See [Fees](/concepts/fees). Every call made with your key counts toward the month, except calls rejected for rate limiting. Months run in UTC and reset on the 1st. Responses carry your limits in headers: | Header | Meaning | |---|---| | `X-RateLimit-Limit`, `X-RateLimit-Remaining` | This minute's limit and what's left | | `X-Quota-Limit`, `X-Quota-Remaining` | This month's calls and what's left (plans with a cap) | ## Usage `GET /usage` returns your plan, calls this month, what's left, when it resets, and calls broken down by endpoint and by day. ```json { "code": 200, "message": "Usage retrieved successfully", "data": { "key": { "keyId": "key_a3f08cd4ce47", "name": "Acme Remit, production" }, "month": "2026-11", "plan": { "id": "sandbox", "label": "Free", "ratePerMinute": 60, "monthlyCalls": 5000 }, "calls": 2, "remaining": 4998, "resetsAt": "2026-12-01T00:00:00.000Z", "byRoute": [{ "route": "POST /forwards", "calls": 1, "errors": 0 }], "byDay": [{ "day": "2026-11-07", "calls": 2, "errors": 0 }] } } ``` ## The envelope Every response, success or error, has the same shape: ```json { "code": 201, "message": "Quote generated successfully", "data": { "…": "…" } } ``` Validation errors add an `errors` array: ```json { "code": 400, "message": "Validation failed", "errors": ["amount must be a positive decimal with up to 18 decimals"] } ``` ## Amounts Amounts are **decimal strings** (`"150000"`, `"725.50"`), never JSON numbers, so nothing is lost to floating point. ## Errors | Code | When | What to do | |---|---|---| | `400` | Unknown asset or rail, bad amount | Check [notation](/concepts/notation) and `GET /currencies/{code}` for rails | | `401` | Missing, invalid or revoked key | Send a valid `x-api-key` | | `404` | Unknown quote id or route | Check the id | | `422` | No usable route at this size right now | Read the message: it names how many ads were excluded and why. Try a different size, rail or time | | `429` | Over the per-minute limit, or this month's calls are used up | Per minute: back off and retry. Monthly: wait for the 1st or upgrade | | `502` | An upstream venue or solver failed | Retry; the quote's `warnings` name the venue | # Asset notation Source: https://docs.landedfx.com/concepts/notation How to name what you send and what should arrive. `from` and `to` take one of two shapes. ## Local currency An ISO 4217 code, optionally followed by a payment rail: | Value | Meaning | |---|---| | `KES` | Kenyan shillings, any payment method | | `KES:mpesa` | Kenyan shillings paid or received over M-Pesa | | `NGN:bank` | Naira by bank transfer | | `BRL:pix` | Brazilian real over Pix | | `INR:upi` | Indian rupees over UPI | Rails: `mpesa`, `pix`, `upi`, `mobile_money`, `wallet`, `bank`, `cash`, `card`, `balance`, `other`. Not every rail exists in every currency. `GET /currencies/{code}` lists the rails available, with the venue payment methods behind each. See [Payment rails](/concepts/rails). ## Tokens `SYMBOL:chain`: | Asset | Chains | |---|---| | USDT | `tron`, `bsc`, `eth`, `sol`, `ton` | | USDC | `base`, `eth`, `arb`, `sol` | | cNGN | `base` (routed through Base DEXes by Relay) | `GET /swap/assets` returns the current list and which provider routes each asset. # All-in cost Source: https://docs.landedfx.com/concepts/all-in-cost How allInBps is measured, and why it's the one number to compare. `allInBps` is the total cost of a route against mid-market, in basis points (100 bps = 1%). ``` allInBps = (1 − amountOut ÷ idealAmountOut) × 10,000 ``` `idealAmountOut` is what the amount would buy at the **mid-market rate with nothing charged**. USDT and USDC count as one dollar each, because that's how P2P venues price them. ## The mid-market rate For each currency we take the median of the five best ask prices and the five best bid prices on each venue, average them into a venue mid, then take the median across venues. A venue whose book is crossed by more than 2% is left out of the mid. ## Leg costs Each step in `route.steps` carries its own `costBps`, measured against that leg's fair value: | Leg | Cost | |---|---| | P2P buy | How far the ad's price is above mid | | P2P sell | How far the ad's price is below mid | | Withdrawal | The venue's network fee as a share of the amount | | Swap | The provider's spread and fees plus the sender's gas | A **negative** leg cost means the leg paid you. That's common on swaps from USDC into USDT, since USDT often trades a fraction below USDC. When there's no reliable mid for a currency, or the destination isn't a dollar stablecoin, `allInBps` falls back to the sum of leg costs, and the quote says so in `warnings`. # Fees Source: https://docs.landedfx.com/concepts/fees Everything LandedFX charges, what other parties charge, and who receives each. ## What LandedFX charges | | Fee | Notes | |---|---|---| | **API, free plan** | $0 | 60 requests a minute, 5,000 calls a month | | **API, Growth** | $99 for 30 days | 300 requests a minute, 250,000 calls a month across your account | | **API, Scale** | $499 for 30 days | 1,200 requests a minute, 2,000,000 calls a month across your account | | **Quotes and routing** | $0 | LandedFX adds nothing to the routes it prices | | **Pay per call (x402)** | $0.01 a quote or carry quote, $0.02 a rate lock | Only for requests with no API key. See [Build with AI](/guides/ai-tools#pay-per-call-with-x402) | | **Earn: deposit and withdrawal** | $0 | | | **Earn: yearly fee** | 0% | | | **Earn: performance fee** | 10% of gains | Only on gains above the vault's previous high. Applies from about 12:24 UTC on November 10, 2026 | The contract caps Earn's fees at 2% a year and 20% of gains. Raising a fee waits out a 2-day timelock, so depositors can leave first. Read the live numbers from `fees` on `GET /vaults/{id}`. ## What you can charge If you build on LandedFX, you can add your own fee of up to 1% on Earn deposits with `integratorFee`. It's paid to your wallet, and LandedFX takes no cut. See [Recipes](/guides/recipes#offer-earn-in-your-app-with-your-own-fee). ## What other parties charge These costs go to others, not LandedFX. On quotes they're already inside `amountOut` and `allInBps`, so what you see is what's left after them. | Cost | Paid to | |---|---| | P2P price gap against the mid-market rate | The ad's seller | | Exchange withdrawal fees | The exchange | | Swap and bridge fees | Relay or NEAR Intents, and their solvers | | Network gas | The network | | Trading fees on rate locks | Numo | | Card and bank top-ups in Earn | The payment provider, shown before you pay | In the Earn app, gas on Base is covered for smart wallets, so a deposit needs no ETH. If you build your own integration, your users pay their own gas unless you sponsor it. # How routing works Source: https://docs.landedfx.com/concepts/routing What the router considers, and how it picks. Every quote builds a set of complete candidate routes, prices each from end to end, and returns the one that lands the most. ## Local currency → token **Find usable ads.** Pull live ads from every venue for the currency, at your exact amount, on your rail. Keep ads whose limits fit the amount, that hold enough USDT, with at least 90% completion and 50 completed orders. **Screen counterparties.** The six best-priced usable ads get their terms [screened](/concepts/screening). Ads that fail are dropped. **Leave the venue.** For the best ad on each venue, price a withdrawal on every network (Tron, BNB Chain, Ethereum, Solana, TON) using that venue's fees. **Swap to the destination.** For each network, ask Relay and NEAR Intents to swap USDT into the destination asset and keep the cheaper, gas included. **Rank.** Sort every venue × network route by amount landed. Return the best and up to four distinct alternatives. ## Token → local currency The mirror image: swap into USDT on each network, deposit to a venue (venues don't charge for deposits), then sell to the best usable bid on your rail. ## Local currency → local currency Buy USDT with the first currency and sell it for the second, either **on one venue** (no withdrawal, no network fee) or **across venues**, moving USDT on the venue's cheapest network. Whichever lands more wins. In live tests, buying shillings on Binance and selling naira on Bybit beat staying on one venue by 8 bps. ## What the router won't do It won't route through an ad it can't fill at your size, an ad with failing terms, or a network the venue has disabled. If nothing is left, you get a `422` naming how many ads were excluded and why. # Payment rails Source: https://docs.landedfx.com/concepts/rails Pricing the way money actually moves on the local side. Two ads with the same price aren't the same if one takes M-Pesa and the other only takes a bank you can't pay from. LandedFX maps every venue payment method to a rail, so you can quote the rail you actually use. | Rail | Matches, for example | |---|---| | `mpesa` | M-Pesa Kenya (Safaricom), M-Pesa Paybill, Pochi la Biashara | | `pix` | Pix | | `upi` | UPI, Paytm, PhonePe, Google Pay | | `mobile_money` | MTN MoMo, Airtel Money, Orange Money, Wave, Telebirr | | `wallet` | OPay, PalmPay, Kuda, Nequi, Mercado Pago, GCash, bKash, Easypaisa | | `bank` | Bank transfer, SPEI, SEPA, IMPS, NEFT, PSE, CBU/CVU | | `cash` | Cash in person, cash deposit | | `card` | Card payments | `GET /currencies/KES` returns the rails available in Kenya and the venue methods behind each. Leave the rail off (`KES`) to accept any method. # Counterparty screening Source: https://docs.landedfx.com/concepts/screening How P2P ads with risky terms are kept out of your routes. P2P ads carry free-text terms. Some are harmless ("pay in your own name"). Others are classic fraud setups: move the chat to WhatsApp, pay a different name, mark as paid early. In the Nigerian market, about one in five top ads with terms asked for an off-platform contact. Before a route uses an ad, **Jev**, a decision model from TypeSafe, reads its terms in any language and returns two probabilities: | Score | Question | Excluded at | |---|---|---| | `redFlag` | Does it bypass the venue's escrow or match a known scam pattern? | ≥ 0.60 | | `restrictive` | Would it slow or block a standard payment from an own-name account? | ≥ 0.70 | The model scores; code decides the cut-off. Each ad's scores show up in the route's `meta.screened` and in `GET /currencies/{code}/ads`. Verdicts are cached per ad and per version of its terms, so an ad is re-screened only when its terms change. Only the six best-priced usable ads per leg are screened on each quote, which keeps it fast. Binance hides ad terms in its public search, so screening applies to the ads that publish them. # Confidence Source: https://docs.landedfx.com/concepts/confidence How sure LandedFX is that the quoted price will hold. Every quote returns `confidence.level` (`high`, `medium` or `low`) and the `reasons` behind it. | Level | When | |---|---| | `high` | Every P2P leg has at least three usable ads, the best three within 150 bps of each other, and a reliable mid-market rate | | `medium` | A leg has only two usable ads, its prices are spread wide, or a mid-market rate is missing | | `low` | A leg has a single usable ad, or the all-in cost is above 5%, which usually means thin liquidity at this size | Pure swap routes are priced by solver networks and are `high` unless the cost is unusual. A `low` quote is still the best available route, but treat it as a ceiling, not a promise: one ad being taken by someone else can move the price. # Recipes Source: https://docs.landedfx.com/guides/recipes Copy-ready builds, from a live payout quote to Earn inside your app with your own fee. Get a free key from the [dashboard](https://app.landedfx.com/keys) and set it as `LANDEDFX_KEY`. Every recipe uses the live API. ## Price a payout before you send it Show your customer what actually lands, at their exact size, across every P2P ad, rail and swap route. ```bash curl -X POST https://api.landedfx.com/api/v1/quotes \ -H "x-api-key: $LANDEDFX_KEY" \ -H "content-type: application/json" \ -d '{ "from": "USDC:base", "to": "NGN", "amount": "100" }' ``` Use these fields: | Field | Show it as | |---|---| | `amountOut` | What lands, after every cost | | `allInBps` | The total cost against the mid-market rate. See [All-in cost](/concepts/all-in-cost) | | `route.summary` | The route in one line | | `route.steps` | Each step, to execute yourself or hand to your treasury team | | `alternatives` | Other routes to compare | | `confidence` | How far to trust the price. See [Confidence](/concepts/confidence) | | `expiresAt` | When to fetch a new quote | A quote is a price, not a trade: LandedFX doesn't move the money on these routes. ## Offer Earn in your app, with your own fee Your user deposits USDC from their own wallet into the vault, and you earn up to 1% of the deposit. LandedFX never holds the money, and the fee goes straight from your user's wallet to yours in the same confirmation. ```ts const res = await fetch('https://api.landedfx.com/api/v1/vaults/dollar/transactions', { method: 'POST', headers: { 'x-api-key': process.env.LANDEDFX_KEY!, 'content-type': 'application/json' }, body: JSON.stringify({ action: 'deposit', account: userWallet, amount: '1000', integratorFee: { bps: 50, recipient: yourBaseAddress }, // 0.5%; the most is 100, which is 1% }), }); const { data } = await res.json(); // data.preview: { assets: 995, paid: 1000, fees: { integrator: { amount: 5, ... } } } // Show that before they confirm, then have their wallet send data.calls in order. ``` `amount` is what leaves the user's wallet, and your fee comes out of it. At 50 bps on 1,000 USDC, you receive 5 and 995 goes into the vault. - **Smart wallets** can send all the calls as one transaction, so it's one tap. - **Regular wallets** send them one at a time, waiting for each. - **Use your own server:** the API key must stay out of the browser. Tell your users about the fee and that the yield can change. See [Vaults](/guides/vaults) for what the vault guarantees, and [Fees](/concepts/fees) for everything LandedFX charges. ## Accept deposits from any chain The user holds USDT on Tron or USDC on Solana, not USDC on Base. One transaction on their chain swaps, bridges and deposits. ```bash curl -X POST https://api.landedfx.com/api/v1/vaults/dollar/deposit-routes \ -H "x-api-key: $LANDEDFX_KEY" \ -H "content-type: application/json" \ -d '{ "from": "USDT:tron", "account": "TUserTronAddress", "receiver": "0xUserBaseWallet", "amount": "250", "integratorFee": { "bps": 50, "recipient": "0xYourBaseAddress" } }' ``` - `amount` is what lands in the vault here, and `pay` is what it costs in the user's token. So your fee goes on top, unlike the recipe above. - Show `pay` and `feesUsd`, then have the user sign `steps` in order on the origin chain. - `from` can be `ETH:eth`, `ETH:base`, `USDT:tron`, `USDT:bsc`, `USDT:eth`, `USDT:sol`, `USDC:base`, `USDC:eth`, `USDC:arb`, `USDC:sol` or `cNGN:base`. - A non-EVM `account` needs `receiver`: the user's wallet on Base. ## Show a user's balance as it grows ```bash curl https://api.landedfx.com/api/v1/vaults/dollar/accounts/0xUserWallet ``` `value` is what the position is worth now, `earned` is the gain so far, `canWithdrawNow` is what can come out at once, and `apyPct` is the current rate. To withdraw, call `/transactions` with `"action": "withdraw"` and an amount, or `"action": "redeem"` and `"amount": "max"` for everything. ## Know when money moves Stop polling. Add a [webhook](/guides/webhooks) for `vault.deposit` and `vault.withdraw`, and update your ledger when the event arrives. An endpoint receives every wallet's events, which are public on-chain anyway, so match `data.wallet` against your own users. Verify every signature. ## Let an agent pay per call An agent with a Base wallet and no API key can pay $0.01 in USDC for a quote. See [Build with AI](/guides/ai-tools#pay-per-call-with-x402) for the code, and to connect Claude, Cursor or ChatGPT to the API. # Local currency → stablecoin Source: https://docs.landedfx.com/guides/onramp Price a pay-in in local currency that lands as a stablecoin on any chain. ```bash curl -X POST https://api.landedfx.com/api/v1/quotes \ -H "x-api-key: $LANDEDFX_KEY" -H "content-type: application/json" \ -d '{ "from": "KES:mpesa", "to": "USDC:base", "amount": "150000" }' ``` A live result: | Step | In | Out | Cost | |---|---|---|---| | Buy USDT on Binance P2P (M-Pesa) | 150,000 KES | 1,152.60 USDT | 49.6 bps | | Withdraw on BNB Chain | 1,152.60 USDT | 1,152.59 USDT | 0.1 bps | | Swap via NEAR Intents | 1,152.59 USDT | 1,151.07 USDC | 13.2 bps | **1,151.07 USDC landed, 62.6 bps all-in**, against 1,158.32 at mid-market. The next routes withdrew on TON, Ethereum or Solana instead, each a few bps worse. ## Tips - **Name the rail.** `KES:mpesa` and `KES` can price differently. The second may use a bank-only ad you can't pay. - **Quote at your real size.** Ads have minimums and maximums. A route that works for $100 may not exist at $10,000. - **Landing USDT?** Quote `USDT:bsc` or `USDT:sol` directly. The router skips the swap and only withdraws. # Stablecoin → local currency Source: https://docs.landedfx.com/guides/offramp Price a payout from a stablecoin into local currency on a payment rail. ```json { "from": "USDC:base", "to": "NGN:bank", "amount": "500" } ``` A live result: **₦686,767 landed, 46.2 bps all-in.** | Step | In | Out | Cost | |---|---|---|---| | Swap via NEAR Intents | 500 USDC on Base | 500.45 USDT on Solana | −9.0 bps | | Deposit to Bybit P2P | 500.45 USDT | 500.45 USDT | 0 | | Sell USDT on Bybit P2P (bank) | 500.45 USDT | ₦686,767 | 55.1 bps | Note the negative swap cost: USDT on Solana was trading a fraction under USDC, so converting **paid** 9 bps. The router found that by pricing the swap into every network before choosing where to deposit. # Cross-border, local to local Source: https://docs.landedfx.com/guides/cross-border Move value from one local currency to another through USDT. ```json { "from": "KES:mpesa", "to": "NGN", "amount": "100000" } ``` A live result: **₦1,054,466 landed, 104.4 bps all-in.** | Step | In | Out | Cost | |---|---|---|---| | Buy USDT on Binance P2P (M-Pesa) | 100,000 KES | 768.40 USDT | 49.6 bps | | Move to Bybit P2P on BNB Chain | 768.40 USDT | 768.39 USDT | 0.1 bps | | Sell USDT on Bybit P2P | 768.39 USDT | ₦1,054,466 | 55.1 bps | The router compared this with buying and selling on Bybit alone (no transfer), which came to 112.6 bps. Moving between venues was cheaper by 8 bps because the best Kenyan and Nigerian prices sat on different venues. # Rate locks Source: https://docs.landedfx.com/guides/rate-locks Lock today's naira rate for a payment you'll make or receive later. An importer who pays a supplier in 30 days, or a payroll that converts monthly, can lock the rate now. LandedFX prices the lock by walking Numo's cNGN futures book at your size. ```bash curl -X POST https://api.landedfx.com/api/v1/forwards \ -H "x-api-key: $LANDEDFX_KEY" -H "content-type: application/json" \ -d '{ "currency": "NGN", "side": "buy_usd", "amountUsd": 1000 }' ``` | Field | Meaning | |---|---| | `rate` | Naira per dollar you lock until `expiry` | | `premiumVsIndexPct`, `premiumAnnPct` | How far the locked rate is from today's index, over the period and per year | | `filledUsd`, `complete` | How much the book can absorb at this price | | `initialMarginUsd` | USDC collateral Numo requires (25% of notional) | | `orderIntent` | An unsigned Numo order: sign it (EIP-712) and post it to Numo | A live example: locking $1,000 of dollars for 23 days came to **₦1,390.70/$**, 1.09% over the ₦1,375.66 index, walking 7 levels of the book. `side: "buy_usd"` is for whoever needs dollars later. `side: "sell_usd"` is for whoever receives dollars later, or wants [naira carry](/guides/carry): each is the other's natural counterparty. `GET /derivatives/ngn` returns the whole curve: Numo's index, every futures series with its basis and depth, and the options chain. Locks settle on Numo, a cash-settled futures venue on Base. You need a Numo margin account; LandedFX never holds the position or the collateral. # Naira carry Source: https://docs.landedfx.com/guides/carry Compare ways to earn naira rates in dollars, priced from live markets. Naira pays far more than dollars, because it is expected to weaken. `POST /carry/quotes` prices every way to capture that rate in USDC, side by side, so you can see what each one really earns and risks. ```bash curl -X POST https://api.landedfx.com/api/v1/carry/quotes \ -H "x-api-key: $LANDEDFX_KEY" -H "content-type: application/json" \ -d '{ "currency": "NGN", "amountUsd": 1000, "hedgeRatio": 0.5 }' ``` ## Strategies | Strategy | What it does | On-chain | |---|---|---| | Naira yield, unhedged | Earn the Treasury-bill rate, convert back at maturity | Needs a licensed partner | | Naira futures carry | Long cNGN futures earn the futures premium if the naira holds | Yes, on Base | | Futures carry with crash insurance | Adds a Numo put that caps the loss past its strike | Yes | | Naira yield, hedged (full or partial) | Lock the rate back to dollars with short cNGN futures | Needs a licensed partner | ## How to read a strategy Each strategy returns: - `scenarios`: the APY if the naira holds, weakens as the futures price implies, or weakens 10% or 25% a year. Rates are per year and applied over each strategy's own length, so strategies compare fairly. - `suddenDevaluation25Pct`: the return over the period if the naira drops 25% at once. - `maxLossPct`: the most you can lose, when insurance caps it. - `breakEvenDevaluationPct`: the weakening at which the strategy earns nothing. - `capacityUsd`: how much can be deployed today at this price. ## What live markets say today With the naira Treasury bill at 15.8% and Numo futures pricing about 11.9% a year of weakening: - **Unhedged** earns about 15% a year if the naira holds and breaks even at about 7% weakening over six months. - **Hedging** costs roughly the expected weakening, so most of the premium goes. That's covered interest parity, not a fee. - **Insurance** is expensive because Numo's options book is small. It gets cheaper as more importers lock rates, since every lock is the other side of a carry position. Use `yieldPct` to price a different naira rate you can access, such as a money-market fund. These are prices, not an offer. Yield strategies can lose money, and selling them to others may require a licence where you operate. # Vaults Source: https://docs.landedfx.com/guides/vaults Let your users earn dollar yield in USDC, with one confirmation and no custody. The LandedFX Dollar vault is an ERC-4626 vault on Base, with the id `dollar`. Your users deposit USDC, get vault shares, and earn what the vault's strategies earn, which today is dollar lending through Spark. Naira carry isn't part of this vault. You build the transactions with LandedFX, and your user's wallet or your custodian signs them. LandedFX never holds keys or funds. No API key is needed. If you send one, deposits you build are attributed to you. ## Deposit in one confirmation ```bash curl -X POST https://api.landedfx.com/api/v1/vaults/dollar/transactions \ -H "content-type: application/json" \ -d '{ "action": "deposit", "account": "0xUserWallet", "amount": "1000" }' ``` You get back `calls`, already simulated against the chain: | Wallet | How to send it | User confirms | |---|---|---| | Smart wallets (Privy, Coinbase Smart Wallet, Safe) and EIP-5792 wallets | Send `calls` as one batch (`wallet_sendCalls`) | Once | | Plain wallets (MetaMask and others) | Sign `permit.typedData`, then send `permit.thenCall` with the signature | Once | | Custodians (Fireblocks, Copper, Anchorage) | Submit each call as a contract call from the vault account | Per your policy | If a call would fail, you get a `422` that says why ("the vault can take 40,000 USDC more right now") instead of a failed transaction. ## Deposit from any token, on any chain Your user holds USDT on Tron, USDC on Solana, or ETH on Ethereum? One origin-chain transaction swaps, bridges and deposits it. ```bash curl -X POST https://api.landedfx.com/api/v1/vaults/dollar/deposit-routes \ -H "content-type: application/json" \ -d '{ "from": "USDT:tron", "account": "TUserTronAddress", "receiver": "0xUserBaseWallet", "amount": "250" }' ``` `amount` is the USDC that lands in the vault; `pay` tells the user what that costs in their token. Sign the returned `steps` in order on the origin chain. Relay runs the swap, the bridge and the deposit on Base, and pays the gas there. Live quotes for a 250 USDC deposit (November 2026): | Paying with | Pays | Fees | Signatures | |---|---|---|---| | USDC on Arbitrum | 250.06 USDC | $0.06 | approve + deposit | | USDC on Solana | 250.09 USDC | $0.09 | 1 | | USDT on Ethereum | 250.36 USDT | $0.12 | approve + deposit | | ETH on Ethereum | 0.112 ETH | $0.33 | 1 | | USDT on BNB Chain | 251.34 USDT | $1.06 | approve + deposit | | USDT on Tron | 250.46 USDT | $2.01 | approve + deposit | The approval is only needed the first time a wallet uses that token. Bitcoin isn't routable straight into the vault yet: swap it to USDC on Base with `POST /swap/quotes` first. ## Withdraw everything ```json { "action": "redeem", "account": "0xUserWallet", "amount": "max" } ``` The vault pulls from its strategies as needed. Withdrawals are never paused. ## Read the vault and a position | Endpoint | Returns | |---|---| | `GET /vaults` | Every vault with TVL, share price, liquidity, fees and allocations | | `GET /vaults/{id}` | One vault, live from the chain | | `GET /vaults/{id}/accounts/{wallet}` | Shares, their value, what the wallet can withdraw now, and its USDC balance | | `GET /vaults/{id}/history?days=30` | Share price and TVL over time, with realised APY | ## What the vault guarantees The rules live in the contract, not in our servers: - Depositors can always withdraw. Pausing stops new deposits only. - Funds move only between the vault and approved strategies, and strategies can only return funds to the vault. - New strategies, higher caps and higher fees wait out a timelock before they apply. - Fees are capped in code at 2% a year and 20% of gains above the high-water mark. Naira carry is in testing as a separate, opt-in vault and isn't open to deposits. To see how it's priced, see [Naira carry](/guides/carry). # Executing swap legs Source: https://docs.landedfx.com/guides/executable-swaps Turn a priced stablecoin leg into a transaction your wallet signs. Quotes are indicative. To execute a swap leg, request an **executable** swap quote with your own addresses. ```bash curl -X POST https://api.landedfx.com/api/v1/swap/quotes \ -H "x-api-key: $LANDEDFX_KEY" -H "content-type: application/json" \ -d '{ "from": "USDT:tron", "to": "USDC:base", "amount": "725", "executable": true, "user": "", "recipient": "" }' ``` `data.quotes` is sorted cheapest all-in first. What you get depends on the provider: | Provider | Returns | You do | |---|---|---| | Relay | `steps`: unsigned transactions and signatures | Sign and send each step from `user` | | NEAR Intents | `depositAddress` | Send exactly `amountIn` of `from` to it | Track either with `GET /swap/status?provider=relay&id=` or `provider=near&id=`. Executable quotes refuse placeholder or burn addresses, and LandedFX never signs or holds funds. Check `minAmountOut` and the deadline before sending. # Webhooks Source: https://docs.landedfx.com/guides/webhooks Get a signed POST when money moves in a vault or the naira risk level changes, instead of polling. Add an endpoint under **Integrations** in the [dashboard](https://app.landedfx.com/integrations), choose your events, and copy the signing secret. It is shown once. Use **Send test** to see a delivery straight away. ## Events | Event | When it fires | `data` | | --- | --- | --- | | `vault.deposit` | A deposit is indexed from the chain | `vaultId`, `wallet`, `assets`, `asset`, `shares`, `txHash`, `blockNumber` | | `vault.withdraw` | A withdrawal is indexed from the chain | The same fields | | `risk.level_changed` | The [naira risk watchdog](/guides/ai-tools#naira-risk-watchdog) moves between `calm`, `watch` and `step_aside` | `currency`, `level`, `previousLevel`, `reasons` | | `webhook.test` | You press **Send test** | `message` | An endpoint receives events from after it was created. It never receives a backfill of older ones. ## What you receive ```http POST /landedfx HTTP/1.1 Content-Type: application/json User-Agent: LandedFX-Webhooks/1.0 LandedFX-Signature: t=1794000000,v1=5f8a... LandedFX-Event-Id: deposit_0xabc..._12 LandedFX-Event-Type: vault.deposit { "id": "deposit_0xabc..._12", "type": "vault.deposit", "createdAt": "2026-11-09T21:30:00.000Z", "data": { "vaultId": "dollar", "wallet": "0x...", "assets": 1000, "asset": "USDC", "shares": "1000000000000", "txHash": "0xabc...", "blockNumber": 54700000 } } ``` ## Verify the signature Anyone can POST to a public URL, so check every request. The signature is an HMAC-SHA256 of `.` using your secret. Use the raw bytes you received: parsing and re-serialising the JSON can change them. ```ts import { createHmac, timingSafeEqual } from 'node:crypto'; export function isFromLandedFX(rawBody: string, header: string, secret: string, toleranceSeconds = 300) { const parts = Object.fromEntries(header.split(',').map((p) => p.split('='))); const t = Number(parts.t); if (!Number.isFinite(t) || !parts.v1) return false; if (Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false; // too old: possibly a replay const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest(); const given = Buffer.from(parts.v1, 'hex'); return given.length === expected.length && timingSafeEqual(given, expected); } ``` ```python import hashlib, hmac, time def is_from_landedfx(raw_body: bytes, header: str, secret: str, tolerance_seconds: int = 300) -> bool: parts = dict(p.split("=", 1) for p in header.split(",") if "=" in p) if "t" not in parts or "v1" not in parts or not parts["t"].isdigit(): return False if abs(time.time() - int(parts["t"])) > tolerance_seconds: return False # too old: possibly a replay signed = parts["t"].encode() + b"." + raw_body expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest() return hmac.compare_digest(expected, parts["v1"]) ``` ## Respond, retry and duplicates - **Return any 2xx within 10 seconds.** Do the slow work after you respond. Redirects are not followed and count as a failure. - **Failures retry** after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 12 hours, about 21 hours in all. After that the delivery is marked failed. - **Handle duplicates.** Delivery is at least once, so store `id` and ignore one you have already handled. - **Don't rely on order.** Use `createdAt`, and `blockNumber` for vault events. The dashboard shows each endpoint's recent deliveries, and the log is kept for 30 days. ## Endpoint rules URLs must use `https` on the standard port and resolve to a public address. Each account can have 5 endpoints. **Rotate** replaces the secret and the old one stops working at once, so have the new one ready to deploy. # Market data Source: https://docs.landedfx.com/guides/market-data Benchmark corridors with live and historical executable costs. Every 15 minutes LandedFX prices every currency at **$100, $1,000 and $10,000**, on both sides, and keeps the result. This isn't a headline rate: it's the best usable ad at that size against mid-market. | Endpoint | Returns | |---|---| | `GET /market/overview?sizeUsd=1000` | Every corridor's current buy, sell and round-trip cost, plus coverage totals | | `GET /market/history/{code}?hours=168&sizeUsd=1000` | Mid-market rate, best prices and costs over time | | `GET /market/swap-costs?hours=24` | Stablecoin swap cost by source chain and provider | | `GET /currencies/{code}/ads?side=ask&amount=…` | Every ad considered for one leg, with why it was kept or dropped | Use it to benchmark a provider's quotes against the real market, choose which rail or chain to ask counterparties to use, or spot when a corridor is unusually expensive. # Build with AI Source: https://docs.landedfx.com/guides/ai-tools Connect Claude, Cursor, ChatGPT or any MCP client to live LandedFX quotes, market data, vaults and these docs. LandedFX runs a remote [MCP](https://modelcontextprotocol.io) server. Connect it to your AI tool and it can price real routes, read live corridors and vaults, and look things up in these docs while it writes your integration. ```text https://api.landedfx.com/mcp ``` It uses Streamable HTTP. A key is optional: without one, everything works except quotes, rate locks and carry pricing, which take a key or an [x402 payment](#pay-per-call-with-x402). Send the key as the `x-api-key` header, or as `Authorization: Bearer `. Calls through MCP count against your key exactly like direct API calls. No key yet? Ask your assistant to "get me a free LandedFX API key". It calls `get_free_api_key` with your name and email, and shows the key once. ## Connect your tool **Claude Code** ```bash claude mcp add --transport http landedfx https://api.landedfx.com/mcp \ --header "x-api-key: $LANDEDFX_KEY" ``` **Cursor** Add to `.cursor/mcp.json` in your project, or `~/.cursor/mcp.json` for every project: ```json { "mcpServers": { "landedfx": { "url": "https://api.landedfx.com/mcp", "headers": { "x-api-key": "lfx_live_…" } } } } ``` **VS Code** Add to `.vscode/mcp.json`: ```json { "servers": { "landedfx": { "type": "http", "url": "https://api.landedfx.com/mcp", "headers": { "x-api-key": "${input:landedfx-key}" } } }, "inputs": [{ "id": "landedfx-key", "type": "promptString", "description": "LandedFX API key", "password": true }] } ``` **Claude and ChatGPT apps** Add a custom connector with the URL `https://api.landedfx.com/mcp`: - **Claude** (desktop and web): Settings → Connectors → Add custom connector. - **ChatGPT**: Settings → Apps & Connectors → Advanced → turn on developer mode, then create a connector. These apps don't send custom headers yet, so they connect without a key: market data, swaps, vaults and docs all work. **Windsurf** Add to `~/.codeium/windsurf/mcp_config.json`: ```json { "mcpServers": { "landedfx": { "serverUrl": "https://api.landedfx.com/mcp", "headers": { "x-api-key": "lfx_live_…" } } } } ``` ## Pay per call with x402 Agents don't need an API key at all. Call a priced endpoint without one and LandedFX answers `402 Payment Required` with [x402](https://x402.org) payment terms: USDC on Base. An x402 client signs the payment and retries, and the response comes back as normal. The payment settles only when the call succeeds. | Endpoint | Price per call | |---|---| | `POST /api/v1/quotes` | $0.01 | | `POST /api/v1/forwards` | $0.02 | | `POST /api/v1/carry/quotes` | $0.01 | ```ts import { wrapFetchWithPayment } from '@x402/fetch'; import { x402Client } from '@x402/core/client'; import { ExactEvmScheme } from '@x402/evm/exact/client'; const client = new x402Client().register('eip155:8453', new ExactEvmScheme(signer)); const pay = wrapFetchWithPayment(fetch, client); const res = await pay('https://api.landedfx.com/api/v1/quotes', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ from: 'KES:mpesa', to: 'USDC:base', amount: '150000' }), }); ``` Requests that send an API key are never charged this way; they use the key's plan. ## Naira risk watchdog `GET /api/v1/risk/ngn` (and the `naira_risk` tool) returns today's naira risk level, `calm`, `watch` or `step_aside`, with the reasons. Every 30 minutes it reads three market signals in code (the naira's 24-hour move, the street premium over the official index, and how fast futures price the naira to fall) and the latest naira headlines, which TypeSafe Jev judges for relevance, direction and policy change. Fixed rules in code set the level. The naira carry strategy, once live, is built to step out of naira exposure at `step_aside`. ## Tools | Tool | What it does | Key | |---|---|---| | `quote_transfer` | Price every route between two assets at a size: best route, alternatives, all-in cost, confidence | Yes | | `list_currencies` | Coverage, or one currency's live rate and rails | | | `get_p2p_ads` | P2P ads that can fill an order at a size, after screening | | | `market_overview` | Live cost of every corridor, or one corridor's history | | | `quote_swap` | Best of Relay and NEAR Intents for a token swap, executable on request | | | `list_swap_assets` | Tokens and chains the swap layer routes | | | `track_swap` | Status of a swap | | | `naira_derivatives` | cNGN index, futures curve and options chain | | | `naira_risk` | Today's naira risk level from the watchdog, with reasons and the headlines AI read | | | `lock_rate` | Price a naira rate lock | Yes | | `price_carry` | Compare naira carry strategies | Yes | | `get_vaults` | Vaults, one vault's state, a wallet's position, or history | | | `build_vault_transaction` | Build a deposit or withdrawal for the user's wallet to sign | | | `vault_deposit_route` | Deposit into a vault from any token on any chain | | | `search_docs` | Search these docs and the API reference | | | `read_doc` | Read a docs page as Markdown | | | `get_free_api_key` | Issue a free API key by name and email | | | `get_usage` | Your plan and usage this month | Yes | Nothing moves funds. Swap and vault tools only return transactions for the user's own wallet to sign. ## Try asking - "What does it cost to send 150,000 KES over M-Pesa and land USDC on Base right now?" - "Which corridor is cheapest to off-ramp $1,000 today?" - "Write a Next.js route that quotes NGN to USDC with LandedFX and shows the route steps." - "Add a LandedFX vault deposit button to my app for Privy smart wallets." ## Docs for LLMs Every page here is also plain Markdown, for tools that read docs directly: - [`/llms.txt`](https://docs.landedfx.com/llms.txt): an index of every page and endpoint. - [`/llms-full.txt`](https://docs.landedfx.com/llms-full.txt): all of the docs in one file. - Any page with `.md` added, such as [`/guides/vaults.md`](https://docs.landedfx.com/guides/vaults.md). - The OpenAPI spec: [`api.landedfx.com/openapi.json`](https://api.landedfx.com/openapi.json). # Coverage Source: https://docs.landedfx.com/coverage Currencies, venues, rails and chains LandedFX prices today. Every currency below has a live USDT P2P market. For the live rate and rails, call `GET /currencies/{code}`, or see the corridor table at [landedfx.com](https://landedfx.com/#coverage). | Region | Currencies | |---|---| | Africa | NGN, KES, GHS, ZAR, EGP, XAF, UGX, TZS, MAD | | Latin America | ARS, BRL, MXN, COP, VES, BOB | | Asia | PKR, INR, BDT, VND, IDR, PHP | | Middle East | TRY | | Europe | UAH, EUR, GBP | | | | |---|---| | P2P venues | Bybit, Binance | | Withdrawal networks | Tron, BNB Chain, Ethereum, Solana, TON | | Swap providers | Relay, NEAR Intents | | Destination tokens | USDT (5 chains), USDC (Base, Ethereum, Arbitrum, Solana), cNGN (Base) | Coverage grows by corridor. Tell us which markets you need at [hello@landedfx.com](mailto:hello@landedfx.com). # API reference Source: https://docs.landedfx.com/api-reference Every endpoint, generated from the LandedFX OpenAPI document. Base URL: `https://api.landedfx.com/api/v1`. Every response uses the [envelope](/authentication#the-envelope), and amounts are decimal strings. - [Quotes](/api-reference/quotes/create-quote): All-in, size-aware quotes and routes. Start with `POST /quotes`. - [Currencies](/api-reference/currencies/get-currency): Coverage, payment rails, live mid-market rates and the ads behind them. - [Market data](/api-reference/market-data/get-market-overview): Corridor costs now and over time, and swap costs by chain. - [Swaps](/api-reference/swaps/create-swap-quote): Best of Relay and NEAR Intents, executable on request. Download the raw spec at [`/openapi.json`](https://api.landedfx.com/openapi.json) to generate a client in any language. # Changelog Source: https://docs.landedfx.com/changelog What's new in the LandedFX API. ## v1.2.0: November 2026 - **Growth and Scale plans**, paid in USDC on Base from the dashboard. Paid limits now apply across your account. See [Plans and limits](/authentication#plans-and-limits). - **[Recipes](/guides/recipes)** for payouts, Earn with your own fee and deposits from any chain, and a [Fees](/concepts/fees) page. - **Webhooks**: signed events for vault deposits and withdrawals and naira risk changes, with retries and a delivery log. See [Webhooks](/guides/webhooks). - **x402 pay-per-call**: agents without a key pay per call in USDC on Base ($0.01 a quote). See [Build with AI](/guides/ai-tools#pay-per-call-with-x402). - **Naira risk watchdog** (`GET /risk/ngn`): calm, watch or step aside, from market signals and AI-judged headlines. - **MCP server** at `https://api.landedfx.com/mcp`: connect Claude, Cursor, ChatGPT or any MCP client to live quotes, market data, swaps, vaults and these docs. See [Build with AI](/guides/ai-tools). - **Docs for LLMs**: [`/llms.txt`](/llms.txt), [`/llms-full.txt`](/llms-full.txt), and every page as Markdown at its path plus `.md`. - **Free API keys** straight from `POST /keys`: 60 requests a minute, 5,000 calls a month. - **Carry vaults** (`/vaults`): live state, positions, history, and deposits from any chain built for the user's wallet to sign. ## v1.1.0: November 2026 - **Large orders** are split across many P2P ads per venue, reading deeper into each venue's book. `maxAds` caps counterparties per leg, and the best single-counterparty route is always offered too. - **BTC and ETH** as sources and destinations, through NEAR Intents and Relay. - **Rate locks** (`POST /forwards`) and the naira futures and options curve (`GET /derivatives/ngn`), via Numo. - **Carry quotes** (`POST /carry/quotes`): unhedged, futures, insured and hedged strategies priced from live inputs. ## v1.0.0: November 2026 - `POST /quotes` across four flows: local currency to token, token to local currency, local to local, and token to token. - 25 currencies on Bybit and Binance P2P, with rail-aware pricing. - AI screening of P2P ad terms. - Live venue withdrawal fees by network. - Best-of Relay and NEAR Intents swaps, executable on request. - Market data: corridor overview, history and swap costs, sampled every 15 minutes. # API endpoints ## GET /api/v1/health Service health ## POST /api/v1/keys Get a free API key Issues a Free-plan key for the live API (60 requests a minute, 5,000 calls a month) straight away. The key is shown once: store it now. One free key per email. Body: - `name` (required) Example: `"Ada Obi"` - `email` (required) Example: `"ada@acme.com"` - `company` Example: `"Acme Remit"` ## GET /api/v1/usage Your plan and usage this month The calling key's plan, its monthly quota and how much is left, with calls broken down by endpoint and by day (UTC). ## GET /api/v1/currencies List covered currencies Every local currency with a live USDT P2P market we price. ## GET /api/v1/currencies/{code} Live rate and rails for a currency Mid-market rate per USDT (median across venues), each venue's best prices and spread, and the payment rails available. Parameters: - `code` (path, required) ## GET /api/v1/currencies/{code}/ads Ads usable at a size Every ad considered for one side at your order size, with why each was accepted or excluded, including the AI screen of its terms. Parameters: - `code` (path, required) - `side` (query, required): `ask`: you buy USDT. `bid`: you sell USDT. - `amount` (query, required): Order size in the local currency - `rail` (query): Payment rail filter ## GET /api/v1/swap/assets Assets the swap layer routes ## POST /api/v1/swap/quotes Best-of Relay and NEAR Intents Indicative by default. With `executable: true` plus your addresses, returns Relay steps to sign or a NEAR deposit address. Body: - `from` (required) Example: `"USDT:tron"` - `to` (required) Example: `"USDC:base"` - `amount` (required): Amount of `from` Example: `"725"` - `executable`: Return an executable quote (needs your addresses) - `user`: Sender address on the origin chain - `recipient`: Receiver address on the destination chain - `refundTo`: Refund address on the origin chain - `slippageBps`: Max slippage in bps Example: `50` - `providers` ## GET /api/v1/swap/status Track a swap Parameters: - `provider` (query, required) - `id` (query, required): Relay requestId or NEAR deposit address ## POST /api/v1/quotes Quote a transfer Prices every route between `from` and `to` at your size, across P2P venues, payment rails, withdrawal networks and swap providers, and returns the best with up to four alternatives. Body: - `from` (required): What you send: a local currency, optionally with a payment rail (`KES`, `KES:mpesa`), or a token (`USDT:tron`). Example: `"KES:mpesa"` - `to` (required): What should arrive, in the same notation. Example: `"USDC:base"` - `amount` (required): Amount of `from`, as a decimal string. Example: `"150000"` - `maxAds`: Most counterparties a P2P leg may use. Large orders are split across ads up to this cap; 1 forces a single ad. ## GET /api/v1/quotes/recent Latest quotes served A live feed of recent quotes, without any caller details. Parameters: - `page` (query): Page number - `limit` (query): Items per page ## GET /api/v1/quotes/{id} Read a quote by id Parameters: - `id` (path, required) ## GET /api/v1/market/overview Coverage and the real cost of every corridor Latest sampled cost of buying and selling USDT against mid-market in every currency, at one order size, plus coverage totals. Parameters: - `sizeUsd` (query): Order size in USD ## GET /api/v1/market/history/{code} Corridor history Mid-market rate, best prices and real costs over time for one currency. Parameters: - `code` (path, required) - `sizeUsd` (query): Order size in USD - `hours` (query): Window in hours ## GET /api/v1/market/swap-costs Stablecoin swap cost by chain and provider Latest and average all-in cost of every swap quoted in the window. Parameters: - `hours` (query) ## POST /api/v1/leads Request design-partner access Body: - `name` (required) Example: `"Ada Obi"` - `email` (required) Example: `"ada@payco.africa"` - `company` (required) Example: `"PayCo"` - `monthlyVolumeUsd` - `corridors` Example: `["KES","NGN"]` - `message` ## GET /api/v1/derivatives/ngn Naira derivatives: index, futures curve and options chain Numo's on-chain naira index, each cNGN futures series with its basis and depth, and the options chain with each put's cost as crash insurance. ## POST /api/v1/forwards Lock a rate for later Prices a rate lock by walking the cNGN futures book at your size, and returns the locked rate, its premium over the index, the margin needed, and an unsigned Numo order to sign. Body: - `currency` (required): Currency to lock against the dollar. Naira today, via Numo cNGN futures. Example: `"NGN"` - `side` (required): `buy_usd`: you will need dollars later (an importer, a payroll). `sell_usd`: you will receive dollars later, or want naira carry. Example: `"buy_usd"` - `amountUsd` (required): Dollar amount to lock Example: `1000` - `market`: A specific futures series, e.g. cNGN-30NOV26. Defaults to the nearest. ## POST /api/v1/carry/quotes Price ways to earn naira rates in dollars Compares unhedged, futures-based, insured and hedged strategies from live inputs: Numo futures and options, the naira Treasury-bill rate, and LandedFX entry and exit costs. Returns each strategy under several devaluation scenarios, with break-even, worst case and capacity. Body: - `currency` (required): Naira today, where Numo provides futures and options. Example: `"NGN"` - `amountUsd` (required): Dollars to deploy Example: `10000` - `tenorDays`: Holding period for the Treasury-bill strategies, in days Example: `182` - `hedgeRatio`: Share of the position to hedge, 0 to 1. Default 1 (fully hedged). Example: `0.5` - `yieldPct`: Override the naira yield (% a year), e.g. a money-market fund rate you can access Example: `18.5` ## GET /api/v1/vaults Carry vaults and their live state ## GET /api/v1/vaults/{id} A vault: TVL, share price, liquidity, fees and allocations Read live from the chain. `liquidity` is what depositors can withdraw right now; `strategies` shows where the rest is working. Parameters: - `id` (path, required) ## GET /api/v1/vaults/{id}/accounts/{account} A wallet's position: shares, value and what it can withdraw now Parameters: - `id` (path, required) - `account` (path, required) ## GET /api/v1/vaults/{id}/history Share price and TVL over time, with realised APY Parameters: - `id` (path, required) - `days` (query) ## POST /api/v1/vaults/{id}/deposit-routes Deposit from any token on any chain Pay with USDT on Tron or Ethereum, USDC on Solana or Arbitrum, ETH and more. Returns the steps to sign on the origin chain: they swap, bridge and deposit exactly `amount` USDC into the vault in one go, with Relay paying gas on Base. Parameters: - `id` (path, required) Body: - `from` (required): What the user pays with: a swap asset key from GET /swap/assets, e.g. USDT:tron, USDC:sol, ETH:eth. Example: `"USDT:tron"` - `account` (required): The wallet paying, on the origin chain. Refunds go back here. Example: `"TNPeeaaFB7K9cmo4uQpcU32zGK8G1NYqeL"` - `amount` (required): USDC to deposit into the vault. The user pays whatever that costs in `from`. Example: `"250"` - `receiver`: Base address that receives the vault shares. Defaults to `account` when it is an EVM address. ## POST /api/v1/vaults/{id}/transactions Build a deposit, withdrawal or redemption to sign Returns ready-to-sign calls, simulated first. Smart wallets and EIP-5792 wallets send them as one batch, so the user confirms once; plain wallets can sign the returned permit instead. LandedFX never holds keys or funds. No API key needed; sending one attributes the volume to you. Parameters: - `id` (path, required) Body: - `action` (required): `withdraw` takes an asset amount; `redeem` takes shares. Example: `"deposit"` - `account` (required): The wallet that signs: the depositor, or the share owner when withdrawing. Example: `"0x70997970C51812dc3A010C7d01b50e0d17dc79C8"` - `amount` (required): A decimal amount: USDC for deposit and withdraw, shares for redeem. "max" withdraws or redeems everything available. Example: `"1000"` - `receiver`: Who receives the shares (deposit) or the USDC (withdraw, redeem). Defaults to `account`.