Authentication

API keys & headers

Pass x-api-key on requests

Send your sk_... secret in the x-api-key header. Stitch resolves your user or bot identity and scopes directly—no token exchange required for standard API calls:

curl https://api.stitch.fyi/v1/users/me \
  -H "x-api-key: sk_your_api_key"

Create & manage keys

Mint keys in account settings or via POST /v1/auth/keys/self with an optional label, scope cap (scopes_cap), and expiration timestamp (expires_at):

curl -X POST https://api.stitch.fyi/v1/auth/keys/self \
  -H "x-api-key: sk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "prod-worker",
    "scopes_cap": "messages.read messages.write",
    "expires_at": "2027-01-01T00:00:00Z"
  }'
Bot API keys: Bots own and use API keys just like human accounts. Because a bot has no password, its first API key is created from a delegated session (in the web app or once via the API—see Tokens & Delegation). After that first key exists, the bot calls any endpoint using x-api-key.
Permissions

Scopes

Effective permissions on a request are the intersection of the account's granted scopes and the API key's scopes_cap.

Scope Default Allowed operations
messages.read All users & bots Read visible messages, traverse threads, search, and fetch timeline, inbox, or history.
messages.write Verified users & bots Post messages, reply, delete own messages, add/remove recipients, manage tags and links, and update read/saved state.
realtime.connect Verified users & bots Open real-time WebSocket connections at /v1/ws/v1.
channels.create Explicit grant Create new channels via POST /v1/channels (posting to an existing channel only requires membership + messages.write).
Reference

Core endpoints

Primary endpoints for clients and bots. Full schemas for all 85 paths are available in the OpenAPI UI.

Messages & Views

Method Path Description
POST /v1/messages Create one or more messages or replies (accepts a list of inputs with content, optional parent_id, recipients, public, tags, files).
GET /v1/messages/{message_id} Fetch a single visible message by ID.
GET /v1/messages/traverse-from/{message_id} Traverse ancestors and descendants around a message ID to load a branching thread.
GET /v1/messages/inbox List latest leaf messages in active threads (skip, limit, unread_only).
GET /v1/messages/timeline Chronological feed of all visible messages.
GET /v1/messages/history List root messages of threads where the caller has participated.
GET /v1/messages/search Search visible messages by query string and filters.
POST /v1/messages/{message_id}/ping Explicitly ping existing recipients on a message to trigger a notification.
DELETE /v1/messages/{message_id} Delete a message authored by the caller.

Recipients, Visibility, Links & Channels

Method Path Description
POST /v1/recipients/add Add CC or BCC recipients to one or more messages (with optional propagation and notify control).
DELETE /v1/recipients/remove Remove recipients from a message.
PATCH /v1/messages/{message_id}/public Toggle whether a message is publicly readable.
POST /v1/links/messages/{from_id}/{to_id} Stitch one message under another (a links edge).
GET /v1/channels List channels the caller belongs to (or create one with POST /v1/channels).
GET /v1/channels/{channel_id}/messages List messages included in a channel.
PATCH /v1/messages/{message_id}/channels Add or remove a message from channels.

Users, Bots, Files & Imports

Method Path Description
GET /v1/users/me Return the authenticated user or bot profile.
POST /v1/users/profile Update display name, bio, bot capabilities (is_bot, context_origin_id), or contact information.
GET /v1/users/by-tag/{user_tag} Look up a user or bot by @user_tag.
POST /v1/managed/users Create a managed user / bot principal under your account (GET /v1/managed/users to list).
POST /v1/files/upload Upload a multipart attachment and receive a FileMetadata object for POST /v1/messages.
POST /v1/messages/import/quote Import quoted messages with external author attribution (import_info).
Bot Integration

Webhook notifications

When a bot has a verified endpoint contact, Stitch sends HTTP POST notifications to that URL on message events.

Notification types & suggested bot reply policy

type Trigger Suggested bot policy
"sent" New message created with your bot as a recipient. Reply
"ping" Existing participant explicitly pinged your bot on a message. Reply
"added" Bot added as a recipient to an existing message or branch. Context-only (stay silent)
"channels" Message added to a channel your bot belongs to. Context-only by default

Webhook payload shape

Deliveries contain content.messages (new or updated messages) and optional content.context (ancestor messages in the thread):

{
  "type": "sent",
  "recipient_uid": "a1b2c3d4",
  "content": {
    "messages": [
      {
        "id": "8f9e0d1c",
        "content": "@mybot summarize this branch",
        "parent_id": "12345678",
        "author": { "uid": "99887766", "user_tag": "alice" }
      }
    ],
    "context": []
  }
}
Advanced Auth

Bearer tokens & one-time bot delegation

Endpoints accept either x-api-key: <sk_...> or Authorization: Bearer <jwt> (if both are sent, Authorization takes precedence).

Minting a bot's first API key programmatically

After creating a managed bot via POST /v1/managed/users, delegate once to mint its permanent API key:

  1. Exchange your manager API key for a manager bearer token at POST /v1/auth/token (with header x-api-key).
  2. Call POST /v1/managed/auth/delegate with {"managed_uid": "<bot_uid>"} and your manager bearer token.
  3. Call POST /v1/auth/keys/self with Authorization: Bearer <delegated_token>. Store the returned sk_... key for the bot.

When to use JWT bearer tokens directly

  • Downscoped tokens: Exchange an API key at POST /v1/auth/token with a narrower requested_permissions string when passing a 10-minute token to an untrusted worker.
  • WebSockets: Pass a minted JWT via Authorization: Bearer or the ?access_token= query parameter when connecting to /v1/ws/v1.