Contents
More and more swaps start as a question to an assistant: "I have USDT on TRON, the receiver wants it on BNB Smart Chain, what will arrive?" The assistant then has to find a service, read it, and get numbers it can trust. Most swap sites are built for a browser and a person: the estimate appears after a script runs, the fee is a tooltip, the route list is a dropdown. An assistant reading the HTML sees very little.
Sablebolt is built so that a machine reads the same facts as a person, from files that are meant to be read. This post lists every one of those files, what is in each, and what an assistant can and cannot do with them. Nothing here is a plan; everything described is served today, and you can open each address in a browser to check.
The files, at one glance
| Address | Format | What it is for |
|---|---|---|
| /llms.txt | Markdown | The index: what the site is, where every page's text twin is, where the API and skills are |
| /llms-full.txt | Markdown | The full text of every page in one file |
| any page + .md (home page: /index.md) | Markdown | The text of that page without the form, scripts or styling |
| /openapi.json | OpenAPI 3.1 | The public API at api.sablebolt.io: assets, routes, limits, quotes, swap status, market data |
| api.sablebolt.io/mcp | Model Context Protocol | The same read operations as MCP tools, for assistants that speak the protocol |
| /.well-known/agent-skills/index.json | JSON | Four read-only skills an agent can offer, each mapped to API endpoints and a documentation page |
| /feed.xml | RSS 2.0 | The blog, one item per post |
| /robots.txt | Text | Crawl rules, the sitemap, and the Content-Signal line |
| /.well-known/security.txt | Text | Where to report a security problem |
llms.txt: the index
llms.txt is a convention for a short, plain file at the root of a site that tells a language model what the site is and where to read more. Sablebolt's version starts with a one-line description ("Account-free crypto swaps between two addresses. Floating rate, network fee shown before you send. No sign-up.") and then lists, as links to the markdown twins:
- Start here — how it works, fees, the list of all pairs, the list of all coins;
- Swap routes — one line per route page, 52 at the time of writing, each named with both networks, such as "USDT TRC-20 → USDT BEP-20";
- Coins — one line per coin page, 28 at the time of writing;
- Blog — every post with its description;
- For agents — the OpenAPI file, the skills index, the RSS feed and the support e-mail.
The file is regenerated at every build from the same data that builds the pages, so it cannot list a route that does not have a page.
/llms-full.txt is the same idea without the links: the markdown twins of all pages, one after another, separated by rules. It is the file to hand to an assistant that should know the whole site in one read.
A markdown twin of every page
Every page on the site exists twice: as HTML for a browser and, at the same path with .md appended, as markdown. /coin/tether becomes /coin/tether.md; /swap/usdt-trc20/usdt-bep20 becomes /swap/usdt-trc20/usdt-bep20.md; the home page is /index.md. The twin is produced from the rendered page at build time: headings, paragraphs, lists, tables and links are kept; the form, buttons, scripts, styles and images are dropped. Each twin starts with three lines of front matter — title, description, url — and is served with the text/markdown content type.
For an assistant this changes what "read the page" means. The pair page's table of address formats, confirmations and fee tokens is a markdown table in the twin, not a grid of styled cells; the FAQ is headings and paragraphs. What the twin does not contain is anything live: the estimate, the minimum, the network fee. Those come from the API, below, because they change every minute and a text file should not pretend otherwise.
openapi.json: the API, described
/openapi.json is an OpenAPI 3.1 document for the API at https://api.sablebolt.io. The important conventions, taken from the file:
- Every amount is a decimal string, such as
"150"or"0.0025", never a floating-point number. - Assets are named by the same slugs as the site's URLs:
btc,usdt-trc20,usdt-bep20,usdc-solana. - Every success is wrapped as
{ "data": ... }; every error as{ "error": { "code", "message" } }, with codes such asvalidation_error,invalid_address,amount_below_min,amount_above_max,pair_unavailable,not_found,rate_limited,upstream_error. - The rate is floating: "Quotes are indicative; the swap is settled at the rate current when the deposit is received."
The endpoints, by the tags the file uses:
| Tag | Endpoint | Returns |
|---|---|---|
| system | GET /v1/health | status, mode (mock or live) and the server time |
| catalog | GET /v1/assets | Every asset with ticker, name, network, confirmations, extraIdName (memo or destination tag, if the chain has one), an explorer URL template, a market id and available |
| catalog | GET /v1/routes | Every published route as from, to, available |
| pricing | GET /v1/limits?from=&to= | min and max for the route |
| pricing | GET /v1/quote?from=&to=&amount= (also POST with a JSON body) | amountTo, networkFee, receiveAmount, rate, fetchedAt |
| swaps | POST /v1/address/validate | Whether an address has the right format for an asset |
| swaps | POST /v1/swaps | Creates a swap and returns the deposit address — the endpoint the site's own form uses |
| swaps | GET /v1/swaps/{id} | Status, stage, both addresses, both transaction hashes |
| market | GET /v1/market/prices?ids= | USD prices for up to 40 market ids, cached for 60 seconds |
| market | GET /v1/market/chart/{id}?days= | Up to 200 price points for 1, 7, 30 or 365 days, cached for 300 seconds |
The quote endpoint also states its arithmetic: receiveAmount = amountTo − networkFee and rate = receiveAmount / amountFrom. So amountTo is the estimate before the payout network fee, networkFee is that fee in units of the receiving asset, and receiveAmount is what the form shows as "You get".
The file is served with an open CORS header, so a browser-based agent can fetch it directly. The quote, validate and create endpoints answer 429 with rate_limited when called too often.
Example: a quote
An assistant that wants to know what arrives for 150 USDT from TRON to BNB Smart Chain calls GET https://api.sablebolt.io/v1/quote?from=usdt-trc20&to=usdt-bep20&amount=150. The shape of the answer, with the live values replaced by what each field means (the numbers change every minute, so they are not printed here):
{ "data": { "from": "usdt-trc20", "to": "usdt-bep20", "amountFrom": "150", "amountTo": "<estimate before the fee>", "networkFee": "<payout fee in USDT on BNB Smart Chain>", "receiveAmount": "<amountTo minus networkFee>", "rate": "<receiveAmount divided by 150>", "fetchedAt": "<ISO time>" } }
If the amount is under the route's minimum, the answer is { "error": { "code": "amount_below_min", "message": "..." } } with status 400, and GET /v1/limits?from=usdt-trc20&to=usdt-bep20 says what the minimum is.
Example: a swap's status
GET https://api.sablebolt.io/v1/swaps/<id> returns, among other fields, status (one of waiting, confirming, exchanging, sending, finished, failed, refunded, expired, hold, unknown), stage (1 to 5, from waiting to finished), depositAddress, payoutAddress, amountFrom, expectedTo, amountTo (the actual payout once known, otherwise null), txIn and txOut — the deposit and payout transaction hashes, null until each exists. The explorer URL template from /v1/assets turns each hash into a link.
The MCP endpoint
Assistants that speak the Model Context Protocol can use the API without reading openapi.json at all. The endpoint is https://api.sablebolt.io/mcp over Streamable HTTP, stateless: every request is a complete JSON-RPC call, there is no session to open and nothing to authenticate. The same rate limits apply as to the REST API.
| Tool | What it returns |
|---|---|
| list_assets, list_routes | the catalog, with availability right now |
| get_limits | minimum and maximum for a route |
| get_quote | the floating estimate: amount to receive, network fee, rate |
| validate_address | whether an address has the right format for an asset, and whether the asset uses a memo |
| get_swap_status | the status page by id: stage, addresses, both hashes |
| swap_page_link | the page where the person completes the swap, with the amount prefilled |
There is no tool that creates a swap. That is deliberate, and it is the same rule the skills index states: the person opens the page, sees both addresses and the memo on screen, and sends the deposit from their own wallet. An assistant can prepare everything up to that point and read the status afterwards.
The skills index
/.well-known/agent-skills/index.json is a small JSON file that tells an agent what it may offer a user on this site. It names the service, points to the OpenAPI file and the support address, and lists four skills:
| Skill | What it does | Endpoints | Documentation |
|---|---|---|---|
| list-routes | Which assets and routes can be swapped right now, with network, confirmations and arrival estimates | /v1/assets, /v1/routes | /pairs.md |
| get-quote | Estimate what arrives for an amount on a route, including the network fee | /v1/limits, /v1/quote | /fees.md |
| compare-networks | For USDT or USDC held on one network, compare arrival time, confirmations, fee token and address format on the others | /v1/assets, /v1/quote | /coin/tether.md |
| swap-status | Stage, deposit address and both transaction hashes of a swap by its id | /v1/swaps/{id} | /how-it-works.md |
All four are read-only. The file then has one line called handoff: to create a swap, send the user to /swap/{from}/{to}?amount={amount} — the swap is created by the person in the form. The pair page reads the amount from the address and fills the form with it, so the hand-off lands on a page that already shows the estimate the assistant discussed.
What an assistant can do with this
Compare networks for USDT. Read /v1/assets and keep the four USDT entries: TRON (TRC-20), Ethereum (ERC-20), BNB Smart Chain (BEP-20) and TON. Each carries confirmations (1, 15, 10 and 20) and extraIdName (a payment ID on TON, none elsewhere). Then call /v1/quote with the same amount for each destination and compare receiveAmount. The twin of the USDT page adds what the API does not have: address formats, the issuer of each version, the fee token needed on each network.
Get an estimate the user can hold you to. /v1/quote gives the estimate, the fee and the time it was fetched. An honest assistant repeats the file's own caveat — the rate floats and is set when the deposit confirms — and does not round the fee away.
Check a swap by id. Given the id from a status link, /v1/swaps/{id} answers with the stage and both hashes. The assistant can say "the deposit was seen, the payout has not been sent yet" from txIn and txOut alone, and link each hash to its explorer.
Answer "can this be swapped at all?" /v1/routes lists exactly the routes that have pages, each with available. A route that is not in the list does not exist on the site; an assistant should say so rather than guess.
What stays with the person
The skills index offers no skill that creates a swap, and the hand-off line says why: the person creates it in the form. There are two practical reasons.
The first is the address. A swap pays out to whatever address is entered, and nothing can undo a payout to the wrong one. The person pastes the address from their own wallet, the form checks its format for the chosen network, and on TON or XRP the person adds the memo or tag the receiving service gave them. An assistant can explain what the address should look like; it should not be the one typing it.
The second is the deposit. After the swap is created the person sends the exact amount from their own wallet to the one-time deposit address. No key, signature or wallet connection is ever given to the site, and none is given to an assistant either. The assistant's job ends at the hand-off link and resumes, if asked, at the status check.
One page is deliberately not for machines. The status page, /status/{id}, is excluded in robots.txt and carries a noindex tag: it belongs to the person who made the swap. The API endpoint behind it answers to anyone who has the id, which is why the id should be treated like the link itself.
robots.txt and the Content-Signal
/robots.txt allows every crawler except three SEO bots that bring no readers, disallows /status/, and names the sitemap. It also carries a line that is newer than the rest of the file:
Content-Signal: search=yes, ai-input=yes, ai-train=yes
Content-Signal is a convention for stating, in robots.txt and as an HTTP header, what a site allows its content to be used for: appearing in search, being fed to an AI model as input when answering a question, and being used for training. Sablebolt says yes to all three, and sends the same line as a header on every response. The site wants to be read, quoted and learned from; the pages are written to be checkable, and the files above exist so that what a machine repeats is what the site says.
Checklist for an assistant, or for a person checking one
FAQ
Can an AI agent make a swap for me through the API?
The OpenAPI file documents the create endpoint because the site's own form uses it, but the skills index offers no create skill and hands the person to the form instead. The address and the deposit are the person's, and the site is built around that.
Does the API need a key or an account?
No. The read endpoints described in openapi.json take no credentials. They are rate-limited, and the quote endpoint answers rate_limited when called too often.
Are the numbers in the markdown twins current?
The twins contain no live numbers on purpose. Estimates, fees and minimums are available only from the API, with a fetchedAt time on each quote.
What does "mode: mock" in /v1/health mean?
The health endpoint reports whether the server is running against the live swap provider or a mock. An assistant should check it before presenting a quote as real.
Why is the status page kept out of search but the API endpoint is open?
The page is private to its owner and is marked noindex and disallowed. The endpoint answers by id, which only the person who created the swap has. Share the id as carefully as the link.
Where do I report a problem with one of these files?
The skills file lists the support address; /.well-known/security.txt lists the security contact for anything that looks like a vulnerability.