Skip to main content
Use Revolt (Stoat) through Corsair: one client, typed API calls. Revolt has been rebranded Stoat, and the published OpenAPI document now points at api.stoat.chat; api.revolt.chat still answers the same API. Create a bot in the client under user settings, or copy a user session token, then pass it here. Things to know before you call:
  • The header depends on the credential. A bot token goes in X-Bot-Token, a user token in X-Session-Token. They are not interchangeable: a bot token in the session header is rejected. Set credential: 'bot' (the default) or 'user'.
  • Authorization is not used. Revolt ignores a bearer header entirely, which is why the plugin writes the token into its own header rather than TOKEN.
  • A custom host is supported. base_url targets a self-hosted instance; the default is Stoat’s production host.
  • Two error bodies. Revolt’s own errors answer { "type": "NotFound", "location": "…" }, sometimes with the field that was missing (MissingPermission adds permission). A bad token (401) or a body that cannot be parsed (422) gets the web framework’s envelope instead, { "error": { "code", "reason", "description" } }. The plugin reads both. A 429 carries retry_after in the body in milliseconds, which the rate-limit handler waits.
  • Messages come back with their authors. With include_users=true a message list answers messages beside the users and members those messages reference, so a caller never has to resolve an author id itself. The plugin sends include_users=true unless you pass false, in which case Revolt answers a bare array and the plugin returns only messages.
  • Cursors, not pages. before and after are message ids, and they contradict each other, so the schema rejects both at once. sort picks the order (Latest by default); Stoat ignores it, along with before and after, when nearby is set.
  • A message needs content or an attachment. An empty post is refused, so the schema requires one of the two.
  • Deletes depend on the channel type. messages.delete removes the message for good. channels.delete deletes a server channel with its messages, leaves a group, and only closes a direct message, whose messages stay.
What you get:
  • 14 typed API operations

Setup

1

Install

2

Add the plugin

corsair.ts
With multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.
3

Choose authentication

4

Connect a tenant

Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see Connect / OAuth.

Example API calls

Read the latest messages in a channel
Send a message to a channel
See the full list on the API page.

What’s next

API reference

Every revolt.api.* operation with input and output types.

Connect / OAuth

createLink, Hub delivery, and tenant connect flows.

Use with agents

Expose this plugin’s operations as MCP tools.