Start here
- `/openapi.json` - OpenAPI 3.1 description of the public HTTP API, with an operation id, a description and typed schemas for every operation.
- `/llms.txt` - the short orientation file, including when an agent should reach for suppy.chat and when it should not.
/mcp- Model Context Protocol endpoint over Streamable HTTP. Read-only tools and Markdown documentation resources, no credentials needed.- `/.well-known/mcp.json` - MCP manifest describing that endpoint.
- `/.well-known/api-catalog` - RFC 9727 catalog of the APIs on this domain, linking each one to its description, its documentation and its status endpoint.
- `/.well-known/ai-catalog.json` - Agentic Resource Discovery manifest of the same resources, with sample queries for registries that index semantically.
- `/api/health` - service status, suitable for a monitor.
- `/docs/install` - the widget installation guide, including the JavaScript API the embed exposes.
Discovery without fetching a page
Every public page carries RFC 8288 Link headers, so a client that issues one HEAD request already knows where everything is: api-catalog, service-desc (the OpenAPI document), service-doc (this page), status (the health endpoint) and describedby (llms.txt).
curl -sSI https://suppy.chat/ | grep -i '^link:'The crawl policy in robots.txt carries a Content Signals line as well: search=yes, ai-input=yes, ai-train=no. Indexing this site and quoting it in an AI answer are both fine - that is what the rest of this page is for - while training a model on it is not.
Markdown instead of HTML
Every public page on suppy.chat answers Accept: text/markdown with a Markdown rendering of the same content, served as text/markdown; charset=utf-8 with Vary: Accept. Browsers asking for HTML keep getting HTML; nothing about the page changes.
curl -sS -H 'Accept: text/markdown' https://suppy.chat/A path that does not exist answers 404 with a short Markdown body explaining the error and linking to this page, the sitemap and llms.txt, so a crawl that goes wrong can correct itself without parsing an HTML error page.
The HTTP API
The API base is https://suppy.chat/api. The endpoints described in the OpenAPI document are the public ones: the service status, the price catalog, the public configuration of a project’s widget, and the conversation endpoints the widget itself uses to start a chat, post a message and read a thread. Dashboard and administrative endpoints are authenticated with an operator session and are deliberately not part of the public contract - they change with the dashboard.
Public endpoints need no credentials. A conversation is instead addressed by its identifier plus the resume token handed out when it was created, which is the credential for that one conversation and nothing else. Operator actions require a signed-in operator with a role on the project.
Errors
Every endpoint under /api answers with JSON, including its failures - an unknown path under /api returns a JSON 404 rather than an HTML page. The error body carries a stable machine-readable code, a human-readable message, a hint describing what to do next and a link to the documentation:
{
"error": "Not found",
"code": "not_found",
"message": "Not found",
"hint": "Check the path against the OpenAPI description at https://suppy.chat/openapi.json.",
"documentation_url": "https://suppy.chat/developers"
}The error field repeats the message so that existing clients keep working. Statuses follow the obvious rules: 400 for a malformed request, 401 and 403 for authentication and authorisation, 404 for something that does not exist, 429 when a rate limit is hit, 500 for a bug on our side and 503 when a dependency such as the database is unreachable. A 503 carries Retry-After; retrying it is the right thing to do.
Rate limits and fair use
Customer messages are limited per conversation by a token bucket that allows a short burst and then refills steadily; exceeding it answers 429. Identical message text repeated within a few seconds is treated as a double tap and returns the message already stored instead of creating a second copy. Other public endpoints are cached at the edge - read the price catalog and widget configuration once per session rather than per page view.
The MCP server
Point an MCP client at https://suppy.chat/mcp using the Streamable HTTP transport. The server advertises tools and resources, requires no authentication and performs no writes: it answers questions about the service, its plans and its documentation.
get_service_status- whether the API and its database are healthy right now.get_pricing- the live seat and module catalog, the same data the plans page renders.search_documentation- full-text search across the published documentation, returning matching sections.get_document- one published page as Markdown, by path.get_widget_embed_code- the exact script tag to install the widget for a given project slug.
The resources it lists are the same Markdown documents, each with a text/markdown mime type and an https://suppy.chat/... URI that resolves in a browser.
Embedding the widget
Installation is one script tag carrying a public project identifier; there is no secret key in the page. The loader exposes a small JavaScript API for opening the chat from your own buttons and for identifying a signed-in customer.
<script
src="https://suppy.chat/widget.js"
data-project="your-project-slug"
async
></script>The installation guide covers custom triggers, asynchronous loading, the queued API and how to verify the installation.