REST API
The endpoints, how to authenticate with an agent's access key, and what each request accepts.
Agents can read this page as plain Markdown at https://teem.so/api.md.
Base URL: https://teem.so/api/v1. Authenticate every request with
Authorization: Bearer teem_pat_.... Create an agent in Settings → API & MCP.
Its access key is shown once. Keep it out of source control, browser code and shared logs.
Each agent acts as one person in one organization. Its permissions follow that membership's current role. Revoking the agent or removing the membership ends access on the next request. The public organization key and the signing secret are not API credentials.
Endpoints
| Method | Endpoint | Operation |
|---|---|---|
| GET | /api/v1/me |
whoami |
| PATCH | /api/v1/me |
update_profile |
| GET | /api/v1/notifications |
read_notification_settings |
| PATCH | /api/v1/notifications |
update_notification_settings |
| GET | /api/v1/organization |
read_organization |
| GET | /api/v1/organization/members |
list_members |
| GET | /api/v1/organization/signing-secret |
read_signing_secret |
| GET | /api/v1/conversations |
list_conversations |
| GET | /api/v1/search |
search |
| GET | /api/v1/conversations/:id |
get_conversation |
| POST | /api/v1/conversations/:id/reply |
reply_to_conversation |
| PATCH | /api/v1/conversations/:id/status |
set_conversation_status |
| DELETE | /api/v1/conversations/:id |
delete_conversation |
| PATCH | /api/v1/conversations/:id/assignment |
assign_conversation |
| GET | /api/v1/slack |
read_slack_status |
| PATCH | /api/v1/slack |
select_slack_channel |
| DELETE | /api/v1/slack |
disconnect_slack |
| POST | /api/v1/conversations/:id/slack/retry |
retry_slack_delivery |
| GET | /api/v1/posts |
list_posts |
| GET | /api/v1/posts/:id |
get_post |
| POST | /api/v1/posts |
create_post |
| PATCH | /api/v1/posts/:id |
update_post_status |
| PATCH | /api/v1/posts/:id/content |
update_post |
| DELETE | /api/v1/posts/:id |
delete_post |
| GET | /api/v1/changelog |
list_changelog |
| POST | /api/v1/changelog |
create_changelog_entry |
| POST | /api/v1/changelog/:id/publish |
publish_changelog_entry |
| POST | /api/v1/changelog/import |
import_changelog_entry |
| PATCH | /api/v1/changelog/:id |
update_changelog_entry |
| DELETE | /api/v1/changelog/:id |
delete_changelog_entry |
| GET | /api/v1/help/topics |
list_help_topics |
| POST | /api/v1/help/topics |
create_help_topic |
| PATCH | /api/v1/help/topics/:id |
update_help_topic |
| DELETE | /api/v1/help/topics/:id |
delete_help_topic |
| POST | /api/v1/help/topics/reorder |
reorder_help_topics |
| POST | /api/v1/help/topics/:id/articles/reorder |
reorder_help_articles |
| GET | /api/v1/help/articles |
list_help_articles |
| GET | /api/v1/help/articles/:id |
get_help_article |
| POST | /api/v1/help/articles |
create_help_article |
| PATCH | /api/v1/help/articles/:id |
update_help_article |
| POST | /api/v1/help/articles/preview |
preview_help_article |
| POST | /api/v1/help/articles/:id/publish |
publish_help_article |
| POST | /api/v1/help/articles/:id/unpublish |
unpublish_help_article |
| POST | /api/v1/help/articles/:id/discard |
discard_help_article_changes |
| DELETE | /api/v1/help/articles/:id |
delete_help_article |
| PATCH | /api/v1/organization |
update_organization |
| POST | /api/v1/organization/public-key/rotate |
rotate_public_key |
| PUT | /api/v1/organization/domain |
connect_domain |
| POST | /api/v1/organization/domain/check |
check_domain |
| DELETE | /api/v1/organization/domain |
remove_domain |
| DELETE | /api/v1/organization |
delete_organization |
GET /me returns user, organization, role, and agent metadata in the existing token
field. User metadata includes
theme_preference (system, light, or dark) and avatar_url (a same-origin path, or null).
Organization metadata includes id, slug, name, key / public_key, board_url,
installed_at, last_seen_at, accent, visitor_theme, and logo_url (a same-origin path, or null). Installation timestamps are
null until the widget records them. The signing secret is excluded from these responses.
Settings updates accept a JSON organization object with name, accent, and/or
visitor_theme (system, light, dark). Members can update these settings. Public-key
rotation, reading the signing secret, and organization deletion require an owner.
Deleting an organization permanently removes its memberships, agents and access keys.
PATCH /organization also accepts logo_base64 or remove_logo: true inside the
organization object. Send standard base64 of a JPG, PNG or WebP file up to 2 MB and
40 million pixels. Upload and removal cannot be combined. The logo is stored as a WebP
within 256 × 256 pixels, preserving its proportions and transparency and removing metadata.
Invalid changes leave the saved logo and settings intact. The response includes logo_url;
the same logo appears in the organization switcher, public pages and hosted widget.
PATCH /me accepts a JSON user object with any of name, theme_preference,
avatar_base64, and remove_avatar. The name must have 1–100 characters after trimming.
For a photo, send standard base64 of a JPG, PNG or WebP file up to 2 MB and 40 million pixels;
use remove_avatar: true to remove it. Upload and removal cannot be combined. Teem stores a
256px square WebP with image metadata removed. The response includes avatar_url.
These personal changes apply across the user's organizations. The theme controls the dashboard;
the organization's visitor theme is separate. The sign-in email cannot be changed here.
GET /notifications returns email, slack, and can_manage_slack. Both channel objects use
new_conversation, bug_report, and feature_request boolean fields. PATCH /notifications
accepts a notification_settings object containing either channel. Email choices belong to the
current membership. Slack choices apply to the organization and require an owner.
Success: { "data": ... }.
Error: { "error": { "code": "...", "message": "...", "details": {} } }.
Validation errors include field errors in details.
401 means the bearer is invalid; 403 means the role cannot perform the action; 404 means the resource is absent from the agent's organization; 422 means invalid input. There is no organization selector: create a separate agent for another organization.
Member lists accept after (the previous meta.next_cursor) and limit (default 25,
maximum 100). Responses contain data and meta.next_cursor; null ends the list.
Cursors are signed and valid only for their original organization and collection.
Conversation lists accept status=open|resolved and use the same pagination fields. A
conversation summary includes the visitor, assignment, latest message, captured page context,
waiting state and timestamps. GET /conversations/:id also includes the ordered thread.
Reply bodies are 1–4,000 characters after trimming. Send an Idempotency-Key header when you
retry a reply; teem writes and mails it once per key. Set membership_id to a current member's
numeric id to assign a conversation, or null to clear it. Status accepts open or resolved.
Conversation ids are opaque cv_... values; a valid id from another organization still returns
404.
PATCH /posts/:id sets a feedback request's status (open, planned, in_progress,
shipped or declined) and an optional public note. teem emails the request's voters when its
status changes. Send "notify": false to skip the email.
GET /slack returns connection state plus the selected workspace and channel without Slack credentials.
Owners may request the joined channel list, select one with PATCH /slack, disconnect with
DELETE /slack, and retry a conversation with POST /conversations/:id/slack/retry. Members can
read status but cannot change it. OAuth remains a signed browser redirect in Settings and has no
agent-authenticated twin.
REST and MCP share 120 requests per minute per agent. A 429 includes Retry-After: 60.
When an organization's trial or subscription has ended, every endpoint except GET /me answers
402 with the code subscription_required, a message saying when it ended, and
details.billing_url for an owner to subscribe. GET /me includes a billing object.
Agent creation/revocation, membership changes and signing-secret rotation require a browser
session. Switching the browser's organization changes that session only.
Example
curl https://teem.so/api/v1/me \
-H "Authorization: Bearer $TEEM_AGENT_KEY"
curl "https://teem.so/api/v1/conversations?status=open&limit=25" \
-H "Authorization: Bearer $TEEM_AGENT_KEY"
curl https://teem.so/api/v1/conversations/cv_example/reply \
-H "Authorization: Bearer $TEEM_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{"body":"We found it and are working on a fix."}'
Help Center publishing is explicit. Create or update a draft, keep the returned editable
revision, then pass that revision to publish:
curl https://teem.so/api/v1/help/articles/ha_example \
-X PATCH \
-H "Authorization: Bearer $TEEM_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{"help_article":{"expected_revision":3,"body":"## Updated answer\n\nNew steps."}}'
curl https://teem.so/api/v1/help/articles/ha_example/publish \
-X POST \
-H "Authorization: Bearer $TEEM_AGENT_KEY" \
-H "Content-Type: application/json" \
-d '{"help_article":{"expected_revision":4}}'
The MCP reference describes agent connections.