Bot API
Reference
Use bearer tokens for member-style bot access and public API tokens for read-only external integrations such as announcements or proposals and decisions feeds.
List Linked Organizations
RebelOps clients read organizations from account_linked_organizations with a join to organizations (identifier fields only). This is the account-level organization list used for cross-device handoff and bot discovery.
curl -X GET "https://auth.rebelops.app/rest/v1/account_linked_organizations?select=id,created_at,organization_id,organizations(id,slug)&order=created_at.asc" \
-H "apikey: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6Imt0d2FkcmtraGF4ZnF5bmJ3aXJkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDk2Mjk5NzgsImV4cCI6MjA2NTIwNTk3OH0.urppeLRkk738LINWlEi_NYiStEIR9uy74UdeH1sjROI" \
-H "Authorization: Bearer <access_token>" \
-H "Content-Type: application/json" Response is a JSON array. Each item includes organizations.slug which can be used to construct the organization URL for subsequent API calls.
[
{
"id": "<link_uuid>",
"created_at": "<timestamptz>",
"organization_id": "<organization_uuid>",
"organizations": {
"id": "<organization_uuid>",
"slug": "<organization_slug>"
}
}
]Organization-Specific Endpoints
The endpoint https://<organization-url>/api returns an OpenAPI-compliant (OpenAPI 3.1) list of available endpoints in the paths object, filtered by caller access. If no access token is provided, it returns only public endpoints. If an access token is provided, it returns endpoints statically accessible to that member role in the organization.
Provide token either as Authorization: Bearer <access_token> or query string ?access_token=<access_token>.
curl -X GET "https://<organization-url>/api" \
-H "Content-Type: application/json"{
"openapi": "3.1.0",
"info": {
"title": "RebelOps Organization API",
"version": "1.72.1+3",
"description": "OpenAPI contract for organization server endpoints. The returned paths are filtered to the supplied token context."
},
"paths": {
"/api": {
"get": {
"operationId": "get_openapi_document",
"summary": "Get OpenAPI document"
}
},
"/api/projects": {
"get": {
"operationId": "get_api_projects"
},
"post": {
"operationId": "post_api_projects"
}
}
},
"x-rebelops-access": {
"authenticated": true,
"isOrganizationMember": true,
"role": "chief",
"tokenMode": "authenticated"
}
}Public Extension Endpoints
Read-only public endpoints use a public API token instead of a member bearer token. Send the token with x-public-api-token: <token> or as ?token=<token>.
The built-in public extension feeds currently include GET /api/public/news and GET /api/public/decisions. The decisions feed returns both proposals and approved decisions. Use the optional status query with proposal, decision, or all to filter the results.
project_idis required.extension_idis optional and can narrow the feed to one extension instance.approved_atisnullfor proposals and a timestamp for approved decisions.
curl -X GET "https://<organization-url>/api/public/decisions?project_id=<projectId>&status=all" \
-H "x-public-api-token: <public_api_token>" \
-H "Content-Type: application/json"{
"decisions": [
{
"id": 71,
"project_id": 12,
"extension_id": 9,
"title": "Confirm launch copy",
"description": "Waiting for final sign-off from the comms lead.",
"description_plaintext": "Waiting for final sign-off from the comms lead.",
"approved_at": null,
"created_at": "2026-05-01T10:15:00.000Z",
"updated_at": "2026-05-01T10:15:00.000Z"
},
{
"id": 72,
"project_id": 12,
"extension_id": 9,
"title": "Launch on Monday",
"description": "Approved after review.",
"description_plaintext": "Approved after review.",
"approved_at": "2026-05-01T11:00:00.000Z",
"created_at": "2026-05-01T10:20:00.000Z",
"updated_at": "2026-05-01T11:00:00.000Z"
}
]
}Send Project Messages
Send bot messages to a project with POST /api/projects/<projectId>/messages. The optional ai field lets you label a message as AI-generated.
aiis an optional string.- Use a short value such as an LLM model name, a bot or AI service name, or a simple marker like
"1"or"true". - The value is stored and returned to clients as plain text. It is not encrypted.
- Keep the value short. Do not put long prompts, secrets, or sensitive content into
ai.
const response = await fetch("https://<organization-url>/api/projects/<projectId>/messages", {
method: "POST",
headers: {
"Authorization": "Bearer <access_token>",
"Content-Type": "application/json"
},
body: JSON.stringify({
message_text: "Build completed successfully.",
supabase_user_id: "<bot-user-id>",
ai: "openai/gpt-5-mini"
})
})
const payload = await response.json() When a message is created through the REST API or the RebelOps websocket, the same ai value is returned in message list responses and in real-time message events.
{
"message": {
"id": 412,
"message_text": "Build completed successfully.",
"message_text_encrypted": "",
"message_type": "user_message",
"event_type": "",
"event_icon": "",
"ai": "openai/gpt-5-mini",
"mentions": [],
"created_at": "2026-03-29T11:42:15.102Z",
"supabase_user_id": "<bot-user-id>"
}
}