Skip to Content
LandedFXDocs

Authentication & errors

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 <key>).

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

PlanPrice for 30 daysRequests per minuteCalls per month
Free$0605,000 per key
Growth$99300250,000 across your account
Scale$4991,2002,000,000 across your account
Without a key30 per IPPublic endpoints only

Need more than Scale? Email hello@landedfx.com.

Upgrade under Plan and 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.

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:

HeaderMeaning
X-RateLimit-Limit, X-RateLimit-RemainingThis minute's limit and what's left
X-Quota-Limit, X-Quota-RemainingThis 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.

{
  "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:

{
  "code": 201,
  "message": "Quote generated successfully",
  "data": { "…": "…" }
}

Validation errors add an errors array:

{
  "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

CodeWhenWhat to do
400Unknown asset or rail, bad amountCheck notation and GET /currencies/{code} for rails
401Missing, invalid or revoked keySend a valid x-api-key
404Unknown quote id or routeCheck the id
422No usable route at this size right nowRead the message: it names how many ads were excluded and why. Try a different size, rail or time
429Over the per-minute limit, or this month's calls are used upPer minute: back off and retry. Monthly: wait for the 1st or upgrade
502An upstream venue or solver failedRetry; the quote's warnings name the venue

On this page