Overview
What this API is, its base URL, and the shape of every answer.
This is the HTTP API the Swapmos interface itself runs on. Every screen in the app is a client of it, which is the useful guarantee: there is no private surface behind the public one, so a third party can drive swaps and futures trades with exactly what is documented here.
Base URL
https://swapmos.comEvery path on these pages is relative to it. Requests and responses are JSON. There is no version in the path: the surface is published by the catalogue endpoint below, and it grows by addition.
Public data needs no key
Markets, funding, the order book, the public tape, candles, swap quotes, token and chain lists, the leaderboard and referral code checks all answer an anonymous request. No account, no header, no signature. If you are building a screen rather than a trader, you never need to read the next page.
Two things need credentials: anything about one account, and anything that changes state. Both go through one signed endpoint, which is what Authentication covers.
The shape of an answer
A success is the payload itself, at the top level. There is no envelope, no success flag and no data wrapper to unwrap.
{ "leverageSteps": [1, 2, 3, 4, 5, 10, 20, 50] }A failure is a fixed shape: a stable machine code, a sentence that is safe to show a user, and meta when there is a machine-readable extra. The HTTP status comes from the same catalogue as the code.
{
"code": "invalid_request",
"error": "That request was missing something or malformed."
}The sentence is never written by an upstream provider. Whatever a provider said goes to our server log; the client is told something from a closed list. Branch on code, not on the words.
What is here
| Prefix | What it serves |
|---|---|
| /api/prep/* | Perpetual futures: markets, rules, funding, the book, the tape, and the signed relay every private call goes through. |
| /api/prep/op/{id} | One dispatcher for the catalogued reads. Ids and parameters are published; see Market data. |
| /api/swap/* | Cross-chain swap quoting, token and chain lists, and transfer status. |
| /api/relayer/voucher | Signs a redemption voucher for a ClubMOS deposit it has verified on chain. |
| /api/admin/* | Operator only. Writes require an admin key and are not part of this API. |
| /mcp | The same capabilities as tools for an AI agent. See the MCP pages. |
Discovery
GET /api/prep/catalogue publishes the catalogued operations and the complete error set as JSON. Write your client against that document rather than against this page and it cannot fall behind.
{
"version": 1,
"operations": [
{
"id": "markets.list",
"summary": "Every listed market with its 24h statistics.",
"endpoint": "/api/prep/op/markets.list",
"method": "GET",
"parameters": [],
"cacheSeconds": 5
}
],
"groups": { "markets": ["markets.list", "markets.get"] },
"errors": [
{
"code": "rate_limited",
"status": 429,
"message": "Too many requests. Wait a moment and try again.",
"retryable": true
}
]
}It is cached for five minutes and carries stale-while-revalidate for an hour, so polling it costs nothing. There are no parameters.
Every response is scrubbed
Success bodies pass through one scrub on the way out. It removes keys that identify infrastructure rather than describe a market, at any depth, and blanks string values that name a routing venue.
- Dropped keys: broker_id, brokerId, broker_name, brokerName, dex_id, builder_id, builder_name, vendor, provider.
- Blanked values: a string that is a venue's name, a venue brand phrase, or a venue hostname. It becomes an empty string, not null.
- A field an upstream document promises may therefore be absent here. That is the scrub working, not a fault.