---
title: llms.txt, OpenAPI and agent skills at Sablebolt
description: What an AI assistant finds on sablebolt.io: llms.txt, a markdown twin of every page, openapi.json, the agent-skills index, the RSS feed and the Content-Signal.
url: https://sablebolt.io/blog/how-sablebolt-talks-to-machines
---

[AI & agents](https://sablebolt.io/blog)

# llms.txt, OpenAPI and agent skills: how Sablebolt talks to machines

Sablebolt Team 23 October 2026 11 min read

Contents

1. The files, at one glance
2. llms.txt: the index
3. A markdown twin of every page
4. openapi.json: the API, described
5. The MCP endpoint
6. The skills index
7. What an assistant can do with this
8. What stays with the person
9. robots.txt and the Content-Signal
10. Checklist for an assistant, or for a person checking one
11. FAQ

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.

≈ 2–5 min 1 confirmation on TRON

[Swap USDT TRC-20 to USDT BEP-20](https://sablebolt.io/swap/usdt-trc20/usdt-bep20)

## 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 as `validation_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](https://sablebolt.io/coin/tether) 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

- Read /llms.txt first; it is short and every link in it exists.
- For facts about a route or a coin, read the `.md` twin, not the HTML.
- For any number — estimate, fee, minimum, status — call the API; never quote a number from a page.
- Pass the amount to the person as `/swap/{from}/{to}?amount=...` and let them enter the address.
- Repeat the rate caveat from openapi.json: the final amount is set when the deposit confirms.
- For a stuck swap, read `status` , `txIn` and `txOut` before suggesting anything, and give the support address from the skills file.

## 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.

## Related posts

- [USDT between networks USDT network fees compared: TRON, BNB Smart Chain, Ethereum, TON, Solana A dated snapshot of what one USDT transfer burns on five networks, how each fee is calculated, and which fee token you must hold to move the money on. 22 October 2026 12 min](https://sablebolt.io/blog/usdt-network-fees-compared)
- [How swaps work Instant swap services compared: account, custody, networks, fee disclosure Eight verifiable criteria for judging an instant swap service, why each one matters, how Sablebolt scores on them today, and how to run the same check on any service yourself. 24 October 2026 11 min](https://sablebolt.io/blog/instant-swap-services-compared)
- [USDT between networks How to pay someone whose USDT wallet is on a different network Their address starts with 0x and your USDT is on TRON. Three ways to make the payment, and what the receiver will see. 14 October 2026 9 min](https://sablebolt.io/blog/pay-usdt-to-a-different-network)
