REST API Reference
The StudioBrain backend exposes a RESTful API on port 8201. All endpoints use JSON request/response bodies and are prefixed with /api/ unless otherwise noted.
Interactive API documentation is available at /docs (Swagger UI) and /redoc (ReDoc) when the backend is running.
Authentication
Most endpoints require a JWT bearer token or session cookie.
Header-based auth:
Authorization: Bearer {jwt_token}Cookie-based auth (web sessions):
The web auth endpoints set httpOnly cookies automatically. Subsequent requests from the browser include the cookie without explicit header configuration.
Obtaining a token:
POST /api/auth/web/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "secretpassword"
}Response:
{
"access_token": "eyJ...",
"token_type": "bearer",
"user_id": "user456",
"role": "admin"
}Common Response Patterns
Success (list)
{
"total": 42,
"offset": 0,
"limit": 50,
"entities": [...]
}Success (single entity)
{
"entity_type": "character",
"entity_id": "rex_marshall",
"name": "Rex Marshall",
"status": "active",
"fields": { ... },
"markdown_body": "...",
"primary_asset": "/Characters/rex_marshall/images/portrait.png",
"validation_errors": [],
"is_valid": true
}Error
{
"detail": "Entity not found: character/unknown_id"
}Common HTTP status codes:
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad request (validation error, malformed input) |
| 401 | Unauthorized (missing or invalid token) |
| 403 | Forbidden (insufficient permissions or feature gate) |
| 404 | Not found |
| 409 | Conflict (entity already exists, sync conflict) |
| 422 | Unprocessable entity (Pydantic validation failure) |
| 429 | Rate limited |
| 500 | Internal server error |
Entities
Unified entity CRUD for all 16 entity types. The {type} path parameter accepts: character, location, district, brand, faction, item, job, quest, campaign, event, dialogue, timeline, assembly, style_bible, universe.
Prefix: /api/entity
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /{type}/schema | Get template schema for entity type | No |
| GET | /{type} | List entities with filtering and pagination | Yes |
| GET | /{type}/{id} | Get single entity by ID | Yes |
| POST | /{type} | Create new entity | Yes |
| PUT | /{type}/{id} | Update entity fields and/or markdown body | Yes |
| DELETE | /{type}/{id} | Soft-delete entity (moves to recycle bin) | Yes |
| POST | /{type}/smart-merge | AI-assisted merge of two entity versions | Yes |
| POST | /{type}/compare | Diff two entity versions | Yes |
| POST | /{type}/import | Import entity from raw markdown content | Yes |
Query Parameters (list endpoint)
| Param | Type | Default | Description |
|---|---|---|---|
offset | int | 0 | Pagination offset |
limit | int | 50 | Maximum results (max 200) |
search | string | — | Full-text search across name and fields |
status | string | — | Filter by status (active, archived, draft) |
sort_by | string | updated_at | Sort field |
sort_order | string | desc | asc or desc |
Create Entity
POST /api/entity/character
Content-Type: application/json
Authorization: Bearer {token}
{
"entity_id": "rex_marshall",
"name": "Rex Marshall",
"status": "active",
"fields": {
"age": "34",
"gender": "male",
"faction": "independent",
"personality_traits": ["resourceful", "paranoid"]
},
"markdown_body": "# Rex Marshall\n\n## Background\n\nA former mechanic..."
}Update Entity
PUT /api/entity/character/rex_marshall
Content-Type: application/json
Authorization: Bearer {token}
{
"fields": {
"age": "35",
"personality_traits": ["resourceful", "paranoid", "loyal"]
}
}Only the provided fields are updated. Omitted fields are unchanged.
Auth and Users
Prefix: /api
Web Auth (cookie-based)
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /auth/web/login | Login with email/password, sets httpOnly cookie | No |
| POST | /auth/web/google-sso | Login via Google SSO token | No |
| GET | /auth/web/session | Get current session info from cookie | Cookie |
User Management
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /auth/register | Register new user | No |
| POST | /auth/login | Login (returns JWT) | No |
| POST | /auth/refresh | Refresh JWT token | Yes |
| POST | /auth/logout | Logout / revoke token | Yes |
| GET | /auth/me | Get current user profile | Yes |
| POST | /auth/set-password | Set new password | Yes |
| POST | /auth/forgot-password | Request password reset email | No |
| POST | /auth/reset-password | Reset password with token | No |
| POST | /auth/create-invite | Create user invitation link | Yes (admin) |
| GET | /auth/validate-invite/{token} | Validate invite token | No |
| POST | /auth/register-with-invite | Register using invite token | No |
OAuth
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /auth/oauth/providers | List configured OAuth providers | No |
| GET | /auth/oauth/google | Initiate Google OAuth flow | No |
| GET | /auth/oauth/google/callback | Google OAuth callback | No |
| GET | /auth/oauth/microsoft | Initiate Microsoft OAuth flow | No |
| GET | /auth/oauth/microsoft/callback | Microsoft OAuth callback | No |
| GET | /auth/oauth/google/drive | Initiate Google Drive OAuth | Yes |
| GET | /auth/oauth/google/drive/callback | Google Drive OAuth callback | Yes |
Users
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /users | List all users | Yes (admin) |
| GET | /users/current | Get current user | Yes |
| GET | /users/{id} | Get user by ID | Yes (admin) |
| PUT | /users/{id} | Update user | Yes (admin) |
| DELETE | /users/{id} | Delete user | Yes (admin) |
| PUT | /users/{id}/password | Change user password | Yes (admin) |
| GET | /users/{id}/api-key | Get user AI API key | Yes |
| POST | /users/{id}/api-key/regenerate | Regenerate AI API key | Yes |
| POST | /api-keys | Create API key | Yes |
| GET | /api-keys | List API keys | Yes |
Registration
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /register | Register new user | No |
StudioBrain Cloud adds tenant management endpoints (
/tenants,/teams), subscription endpoints, permission templates, tenant selection (/auth/web/select-tenant), and invite-based registration. These are not present in core.
Sync and File Operations
Markdown Sync
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /sync/status | Get sync status (running, last result) | No |
| GET | /sync/check-changes | Check for pending file changes | Yes |
| POST | /sync/import-changes | Import detected file changes | Yes |
| POST | /sync/save-to-markdown/{type}/{id} | Write entity to markdown file | Yes |
| POST | /sync/from-markdown/{type}/{id} | Read entity from markdown file into DB | Yes |
| POST | /sync/refresh-all | Full re-sync all markdown to DB | Yes |
| GET | /sync/file-watcher/status | Hybrid file watcher status | No |
Entity Sync (bulk)
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /api/entity/sync/all | Sync all entity types from markdown | Yes |
| POST | /api/entity/sync/{type} | Sync specific entity type | Yes |
| POST | /api/entity/validate/all | Validate all entities | Yes |
Markdown Operations
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /markdown/validate-frontmatter | Validate YAML frontmatter | Yes |
| POST | /markdown/sync-from-files | Sync from filesystem | Yes |
| POST | /markdown/export/{type}/{id} | Export entity as markdown | Yes |
Import
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /import/preview | Preview markdown import without saving | Yes |
| POST | /import/smart | Smart import with AI-assisted field mapping | Yes |
| POST | /markdown/format | Format/normalize markdown content | Yes |
| POST | /validation/fix | Auto-fix common validation issues | Yes |
| POST | /rename-entity | Rename entity (updates ID, files, references) | Yes |
Cloud Sync
App-level Cloud Sync
Prefix: /api/cloud-sync
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /push | Push local changes to cloud (PostgreSQL RLS) | Yes |
| GET | /pull | Pull cloud changes to local | Yes |
| GET | /status | Cloud sync status | Yes |
Desktop Cloud Sync
Prefix: /api/desktop/sync
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /push | Push from desktop to cloud | Yes |
| GET | /pull | Pull from cloud to desktop | Yes |
| GET | /presence | Get online presence info | Yes |
Conflicts
Prefix: /api/conflicts
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | List unresolved sync conflicts | Yes |
| POST | /{conflict_id}/resolve | Resolve a conflict (pick winner) | Yes |
Google Drive
Drive Storage
Prefix: /api/drive/oauth
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /status | Drive connection status | Yes |
| GET | /folders | List Drive folders for picker | Yes |
| POST | /select-folder | Set project folder | Yes |
| POST | /disconnect | Disconnect Drive storage | Yes |
| POST | /test | Test Drive connection | Yes |
Drive Files
Prefix: /api/drive
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /status | Drive connection status | Yes |
| GET | /files | List Drive files | Yes |
| GET | /files/{file_id} | Get file metadata | Yes |
| GET | /files/{file_id}/download | Download file content | Yes |
| POST | /export-entity | Export entity as Google Doc | Yes |
| PUT | /files/{file_id} | Update Drive file content | Yes |
| POST | /files/{file_id}/share | Share file with another user | Yes |
Drive Webhooks
Prefix: /api/drive/webhook
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | “ | Receive Drive change notifications | No (webhook) |
| POST | /register | Register push notification channel | Yes |
| DELETE | /unregister | Stop watching for changes | Yes |
| GET | /status | Webhook registration status | Yes |
Drive Cloud Sync
Prefix: /api/drive
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /cloud-sync-status | Cloud Drive sync worker status | Yes |
| POST | /force-sync | Force immediate Drive sync | Yes |
Billing
Prefix: /api/billing
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /prices | List available subscription prices | No |
| GET | /subscription | Get current subscription details | Yes |
| GET | /usage | Get current BrainBits usage | Yes |
| POST | /checkout | Create Stripe checkout session | Yes |
| POST | /portal | Create Stripe customer portal session | Yes |
| GET | /portal | Redirect to Stripe customer portal | Yes |
| POST | /webhook | Stripe webhook receiver | No (webhook) |
| GET | /status | Billing system status | Yes |
| GET | /invoices | List invoices | Yes |
| PUT | /quota | Update team quota allocation | Yes (admin) |
| POST | /consume-tokens | Consume BrainBits tokens | Yes |
| GET | /team/members | List team members with billing info | Yes |
| PUT | /team/user-quota | Update per-user quota | Yes (admin) |
| GET | /usage-history | Usage history over time | Yes |
| GET | /token-blocks | List available token block purchases | Yes |
| POST | /purchase-tokens | Purchase additional BrainBits | Yes |
| GET | /purchase-history | Token purchase history | Yes |
| GET | /brainbits | Get BrainBits balance | Yes |
| POST | /brainbits/consume | Consume BrainBits | Yes |
Beta Program
Prefix: /api/beta
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /invite | Create beta invite code | Yes (admin) |
| GET | /validate/{code} | Validate invite code | No |
| POST | /redeem | Redeem invite code | Yes |
| POST | /invite/revoke | Revoke an invite code | Yes (admin) |
| POST | /extend | Extend beta period | Yes (admin) |
| GET | /stats | Beta program statistics | Yes (admin) |
| POST | /feedback | Submit beta feedback | Yes |
| GET | /feedback | List feedback submissions | Yes (admin) |
| PATCH | /feedback/{id} | Update feedback status | Yes (admin) |
| POST | /waitlist | Join waitlist | No |
| GET | /waitlist | List waitlist entries | Yes (admin) |
| POST | /waitlist/promote | Promote waitlist entry to invite | Yes (admin) |
Desktop
Prefix: /api/desktop
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /projects | List local projects | No |
| POST | /projects | Create new project | No |
| DELETE | /projects/{name} | Delete project | No |
| POST | /projects/{name}/activate | Activate project | No |
| POST | /projects/{name}/scan | Scan project for entities | No |
| GET | /watcher/status | File watcher status | No |
| POST | /watcher/start | Start file watcher | No |
| POST | /watcher/stop | Stop file watcher | No |
| GET | /sync/status | Desktop sync status | No |
| GET | /sync/queue | View sync queue | No |
| POST | /sync/start | Start sync worker | No |
| POST | /sync/stop | Stop sync worker | No |
| POST | /sync/now | Trigger immediate sync | No |
| POST | /sync/force-push | Force push to cloud | No |
| POST | /sync/force-pull | Force pull from cloud | No |
| GET | /sync/conflicts | List sync conflicts | No |
| POST | /sync/conflicts/{id}/resolve | Resolve conflict | No |
| POST | /ai/chat | Desktop AI chat (offline-capable) | No |
| GET | /ai/providers | List available AI providers | No |
| POST | /auth/login | Desktop auth login | No |
| POST | /auth/callback | Desktop auth callback | No |
| POST | /auth/logout | Desktop auth logout | No |
| GET | /auth/status | Desktop auth status | No |
| POST | /ws/connect | Connect desktop WebSocket | No |
| POST | /ws/disconnect | Disconnect desktop WebSocket | No |
Templates and Rules
Templates
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /templates | List all templates | No |
| GET | /templates/entity-types | List available entity types | No |
| POST | /templates/reload | Reload templates from disk | Yes |
| GET | /templates/{name} | Get template content | No |
| PUT | /templates/{name} | Update template | Yes |
| GET | /templates/{name}/instructions | Get AI generation instructions | No |
| PUT | /templates/{name}/instructions | Update AI instructions | Yes |
Template Categories and Activation
Templates are organized into three categories: entity (world content), document (narrative documents), and core (always-available types). The template activation system lets users opt specific entity types into a project without cluttering the sidebar with unused types.
Prefix: /api/tenant
Note: Despite the
/api/tenantprefix (a naming artifact), these endpoints work in single-tenant core. They operate on the current project without any tenant scoping.
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /available-templates | List all templates with activation status | Yes |
| GET | /active-templates | List activated entity types for a project | Yes |
| POST | /activate-template | Activate a single entity type | Yes |
| DELETE | /deactivate-template | Deactivate a single entity type | Yes |
| GET | /starter-packs | List available starter packs | Yes |
| POST | /activate-starter-pack | Activate a named starter pack | Yes |
List Available Templates
GET /api/tenant/available-templates?project_id=default&category=entity
Authorization: Bearer {token}Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
project_id | string | default | Project scope |
category | string | — | Filter by entity, document, or core |
Response (array of template objects):
[
{
"entity_type": "character",
"label": "Character",
"description": "People, NPCs, and key figures in your world",
"category": "entity",
"source": "standard",
"is_active": true
},
{
"entity_type": "quest",
"label": "Quest",
"description": "Missions, objectives, and tasks",
"category": "core",
"source": "core",
"is_active": true
}
]Core types (dialogue, assembly, quest, timeline) are always active and returned with category: "core".
Get Active Templates
GET /api/tenant/active-templates?project_id=default
Authorization: Bearer {token}Response:
{
"active_types": ["character", "location", "faction"],
"core_types": ["assembly", "dialogue", "quest", "timeline"],
"total_active": 3,
"plan": "indie"
}active_types contains only user-activated Standard types. Add core_types to get the full set of available types for a project.
Activate a Template
POST /api/tenant/activate-template
Authorization: Bearer {token}
Content-Type: application/json
{
"entity_type": "character",
"project_id": "default"
}Returns the same TemplateInfo shape as list items. Enforces plan-based activation limits (Free: 5, Indie: 15, Team/Enterprise: unlimited). Returns 403 if limit exceeded.
Deactivate a Template
DELETE /api/tenant/deactivate-template
Authorization: Bearer {token}
Content-Type: application/json
{
"entity_type": "character",
"project_id": "default"
}Core types cannot be deactivated and will return a 400 error if attempted.
Starter Packs
Starter packs are curated bundles of related entity types. Activating a pack activates all included types in a single operation.
GET /api/tenant/starter-packs
Authorization: Bearer {token}Response:
{
"packs": [
{
"pack_id": "rpg_core",
"name": "RPG Core",
"description": "Characters, locations, factions, quests, and items",
"types": ["character", "location", "faction", "quest", "item"],
"type_count": 5
}
]
}To activate a starter pack:
POST /api/tenant/activate-starter-pack
Authorization: Bearer {token}
Content-Type: application/json
{
"pack_id": "rpg_core",
"project_id": "default"
}Response:
{
"pack_id": "rpg_core",
"project_id": "default",
"newly_activated": ["character", "location", "faction", "item"],
"total_active": 4
}Types that were already active are not counted in newly_activated.
Rules
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /rules | List all rule files | No |
| POST | /rules/reload | Reload rules from disk | Yes |
| GET | /rules/index | Get rules index | No |
| GET | /rules/settings | Get rules settings | No |
| PUT | /rules/settings | Update rules settings | Yes |
| POST | /rules/validate/{type} | Validate entity against rules | Yes |
| GET | /rules/{type} | Get parsed rules for entity type | No |
| GET | /rules/{type}/markdown | Get raw rule markdown | No |
| PUT | /rules/{type}/markdown | Update rule markdown | Yes |
| PUT | /rules/{type}/system-prompt | Update AI system prompt | Yes |
| POST | /rules/{type} | Add new rule | Yes |
| PUT | /rules/{type}/{rule_id} | Update specific rule | Yes |
| DELETE | /rules/{type}/{rule_id} | Delete specific rule | Yes |
Schemas
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /schemas | List all entity schemas | No |
| GET | /schemas/{type} | Get schema for entity type | No |
Project Manifest
The Manifest API provides access to the project manifest, which is a cached index of all files, entities, and assets in the current project. This is used for entity browsing, cache state management, and metadata-first project open.
Prefix: /api/manifest
Manifest Endpoints
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | Get current manifest | Yes |
| POST | /refresh | Trigger manifest refresh | Yes |
| GET | /diff | Get manifest changes since timestamp | Yes |
| GET | /entry/{path} | Get metadata for a single file | Yes |
Get Manifest
Returns the current manifest for the project.
GET /api/manifest
Authorization: Bearer {token}Response:
{
"project_id": "default",
"provider_type": "local",
"manifest_version": 42,
"generated_at": "2026-03-13T18:00:00Z",
"total_entries": 156,
"total_size_bytes": 5242880,
"entries": [
{
"relative_path": "Characters/john_doe/CH_john_doe.md",
"entity_type": "character",
"entity_id": "ch_john_doe",
"entry_type": "markdown",
"size_bytes": 4096,
"checksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"mime_type": "text/markdown",
"remote_modified": "2026-03-13T17:30:00Z",
"preview_available": true
}
]
}Schema fields:
| Field | Type | Description |
|---|---|---|
project_id | string | Project identifier |
provider_type | string | Storage provider (local, s3, gcs, etc.) |
manifest_version | int | Monotonically increasing version number |
generated_at | ISO datetime | When this manifest was generated |
total_entries | int | Total number of entries |
total_size_bytes | int | Total size of all entries in bytes |
entries | array | List of manifest entries |
Entry schema:
| Field | Type | Description |
|---|---|---|
relative_path | string | Path relative to project root |
entity_type | string or null | Entity type if this is an entity file |
entity_id | string or null | Entity ID if this is an entity file |
entry_type | string | One of: markdown, asset, template, rule, other |
size_bytes | int | File size in bytes |
checksum_sha256 | string | SHA256 checksum of file contents |
mime_type | string or null | MIME type of file |
remote_modified | ISO datetime | Last modified timestamp |
preview_available | bool | Whether a preview is available |
Refresh Manifest
Triggers an immediate manifest refresh and returns the updated manifest.
POST /api/manifest/refresh
Authorization: Bearer {token}
Content-Type: application/jsonResponse:
{
"manifest": { ... }, // Full manifest object
"diff": {
"added": ["Characters/new_ch/CH_new_ch.md"],
"removed": ["Characters/old_ch/CH_old_ch.md"],
"modified": ["Documents/notes/DOC_notes.md"]
},
"refreshed_at": "2026-03-13T18:00:00Z"
}Get Manifest Diff
Returns manifest changes since a given timestamp.
GET /api/manifest/diff?since=2026-03-13T00:00:00Z
Authorization: Bearer {token}Query parameters:
| Param | Type | Required | Description |
|---|---|---|---|
since | ISO datetime | Yes | Timestamp to diff from |
Response:
Returns either a diff object or full manifest if the timestamp is too old:
{
"type": "diff",
"diff": {
"added": ["path/to/new_file.md"],
"removed": ["path/to/removed_file.md"],
"modified": ["path/to/modified_file.md"]
}
}or
{
"type": "full",
"manifest": { ... } // Full manifest object
}Get Manifest Entry
Returns metadata for a single file in the manifest.
GET /api/manifest/entry/Characters/john_doe/CH_john_doe.md
Authorization: Bearer {token}Response:
{
"relative_path": "Characters/john_doe/CH_john_doe.md",
"entity_type": "character",
"entity_id": "ch_john_doe",
"entry_type": "markdown",
"size_bytes": 4096,
"checksum_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"mime_type": "text/markdown",
"remote_modified": "2026-03-13T17:30:00Z",
"preview_available": true
}Agent Skills
Agent Skills are YAML-defined AI capability modules that enhance content generation. The API provides two surfaces: a marketplace catalog (skill definitions) and tenant installations (which skills are active for the current tenant).
Prefix: /api/agent-skills
Skill Marketplace
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | List all skills in the marketplace | Yes |
| GET | /{skill_id} | Get details for a specific skill | Yes |
| POST | /registry | Add or update a skill in the registry | Yes (admin/owner) |
| DELETE | /registry/{skill_id} | Remove a skill from the registry | Yes (admin/owner) |
List Skills
GET /api/agent-skills
Authorization: Bearer {token}Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
category | string | — | Filter by category (entity, document, validation, etc.) |
search | string | — | Full-text search across name, description, and skill_id |
featured | bool | false | Return only featured skills |
limit | int | 50 | Max results (1-200) |
offset | int | 0 | Pagination offset |
Response:
{
"skills": [
{
"skill_id": "character_writer",
"name": "Character Writer",
"description": "Specialized in creating deep, consistent character profiles",
"category": "entity",
"tags": ["character", "narrative", "worldbuilding"],
"definition": {},
"prompt_template": "",
"parameters": {},
"min_tier": "free",
"is_featured": false,
"is_builtin": true,
"usage_count": 142,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z"
}
],
"total": 5,
"limit": 50,
"offset": 0
}Get Skill
GET /api/agent-skills/{skill_id}
Authorization: Bearer {token}Returns the full skill record. Returns 404 if the skill is not in the registry.
Add or Update Skill (Admin)
POST /api/agent-skills/registry
Content-Type: application/json
Authorization: Bearer {token}
{
"skill_id": "game_mechanics_validator",
"name": "Game Mechanics Validator",
"description": "Validates game mechanics documentation for consistency and balance",
"category": "validation",
"tags": ["validation", "game-mechanics"],
"definition": {},
"prompt_template": "",
"parameters": {
"max_tokens": 1000,
"strict_mode": true
},
"min_tier": "indie",
"is_featured": false,
"is_builtin": false
}Requires role: admin or role: owner. Creates or updates the skill record (upsert by skill_id).
Remove Skill (Admin)
DELETE /api/agent-skills/registry/{skill_id}
Authorization: Bearer {token}Requires role: admin or role: owner. Returns 404 if the skill is not in the registry.
Tenant Installations
All installation endpoints scope to the authenticated user. In core, this is the single local user. In StudioBrain Cloud, scope is resolved from the JWT’s tenant claim.
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /tenant/installed | List installed skills for the current tenant | Yes |
| GET | /tenant/enabled | List enabled skills with full definitions merged | Yes |
| POST | /tenant/install | Install a skill for the current tenant | Yes |
| POST | /tenant/{skill_id}/enable | Enable an installed skill | Yes |
| POST | /tenant/{skill_id}/disable | Disable an installed skill | Yes |
| DELETE | /tenant/{skill_id} | Uninstall a skill for the current tenant | Yes |
List Installed Skills
GET /api/agent-skills/tenant/installed
Authorization: Bearer {token}Query parameters:
| Param | Type | Default | Description |
|---|---|---|---|
enabled_only | bool | false | Return only enabled installations |
Response:
{
"skills": [
{
"skill_id": "character_writer",
"enabled": true,
"installed_at": "2025-06-01T12:00:00Z",
"installed_by": "user456",
"source": "marketplace",
"source_url": null,
"version": null
}
]
}List Enabled Skills with Full Definitions
GET /api/agent-skills/tenant/enabled
Authorization: Bearer {token}Returns enabled installations merged with their full skill definitions. Use this endpoint when building AI generation prompts that need skill system prompts and capability metadata.
Install a Skill
POST /api/agent-skills/tenant/install
Content-Type: application/json
Authorization: Bearer {token}
{
"skill_id": "character_writer",
"source": "marketplace",
"source_url": null
}source values: marketplace, template_pack, local
If the skill is already installed for this tenant, it is re-enabled rather than duplicated. The skill’s usage_count in the registry is incremented on each install.
Response:
{
"message": "Skill 'character_writer' installed",
"installation": {
"skill_id": "character_writer",
"enabled": true,
"installed_at": "2025-06-01T12:00:00Z",
"installed_by": "user456",
"source": "marketplace",
"source_url": null,
"version": null
}
}Enable or Disable a Skill
POST /api/agent-skills/tenant/{skill_id}/enable
POST /api/agent-skills/tenant/{skill_id}/disable
Authorization: Bearer {token}Toggles the enabled flag on the existing installation. Disabling retains the installation record so the skill can be re-enabled without reinstalling. Returns 404 if the skill is not installed for the tenant.
Uninstall a Skill
DELETE /api/agent-skills/tenant/{skill_id}
Authorization: Bearer {token}Permanently removes the installation record. Returns 404 if not installed. The skill must be reinstalled (via /tenant/install) to be used again.
Agent Skills Error Reference
| Status | Condition |
|---|---|
| 401 | Missing or invalid bearer token |
| 403 | Non-admin/owner attempting registry write operations |
| 404 | Skill not found in registry, or not installed for tenant |
Assets
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /assets | List assets with filtering | Yes |
| GET | /assets/test | Asset system test | No |
| GET | /assets/linked | List assets linked to entities | Yes |
| GET | /assets/uploaders | List available upload providers | Yes |
| GET | /assets/{id} | Get asset by ID | Yes |
| POST | /assets | Create asset record | Yes |
| PUT | /assets/{id} | Update asset metadata | Yes |
| DELETE | /assets/{id} | Delete asset | Yes |
| POST | /assets/scan | Scan all entity folders for new assets | Yes |
| POST | /assets/scan/{type}/{id} | Scan specific entity for assets | Yes |
| POST | /assets/sanitize-ids | Fix invalid asset IDs | Yes |
| POST | /assets/upload | Upload asset file | Yes |
| POST | /assets/auto-tag | AI auto-tag asset | Yes |
| POST | /assets/thumbnail | Generate thumbnail | Yes |
| POST | /assets/ai-rescan | Re-analyze asset with AI | Yes |
| GET | /assets/by-brand/{brand_id} | Get assets for brand | Yes |
| GET | /assets/duplicates | Find duplicate assets | Yes |
| PUT | /assets/{id}/status | Update asset status | Yes |
| POST | /assets/{id}/relationships | Add asset relationship | Yes |
| GET | /assets/{id}/relationships | Get asset relationships | Yes |
| GET | /assets/stats/overview | Asset statistics | Yes |
Asset Queue
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /asset-queue/status | Queue processing status | Yes |
| POST | /asset-queue/pause | Pause queue processing | Yes |
| POST | /asset-queue/resume | Resume queue processing | Yes |
| GET | /asset-queue/asset/{id} | Get asset queue entry | Yes |
| POST | /asset-queue/vram-pressure | Report VRAM pressure | Yes |
| POST | /asset-queue/rescan/{id} | Re-queue asset for analysis | Yes |
| POST | /asset-queue/batch-rescan | Batch re-queue assets | Yes |
File Serving
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /files/{path} | Serve static file | No |
| POST | /upload/character/{id}/image | Upload character image | Yes |
| POST | /upload/location/{id}/image | Upload location image | Yes |
| POST | /upload/brand/{id}/image | Upload brand image | Yes |
| POST | /upload/{type}/{id} | Upload file for any entity | Yes |
Plugins
Plugin Management
Prefix: /api/plugins
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | List all plugins | Yes |
| POST | /install | Install plugin from URL/archive | Yes (admin) |
| POST | /{id}/enable | Enable plugin | Yes (admin) |
| POST | /{id}/disable | Disable plugin | Yes (admin) |
| POST | /{id}/update | Update plugin | Yes (admin) |
| DELETE | /{id} | Uninstall plugin | Yes (admin) |
| POST | /{id}/backup | Backup plugin data | Yes (admin) |
| POST | /{id}/restore | Restore plugin from backup | Yes (admin) |
| GET | /{id}/backups | List plugin backups | Yes |
| GET | /{id}/settings | Get plugin settings | Yes |
| PUT | /{id}/settings | Update plugin settings | Yes (admin) |
| GET | /{id}/settings/user | Get user-specific settings | Yes |
| PUT | /{id}/settings/user | Update user-specific settings | Yes |
| GET | /page/{id} | Serve plugin page | Yes |
| GET | /page/{id}/{subpath} | Serve plugin subpage | Yes |
| GET | /panel/{id}/{panel_id} | Serve plugin panel HTML | Yes |
Plugin Data
Prefix: /api/plugins
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /{id}/data/{record_type} | List plugin data records | Yes |
| POST | /{id}/data/{record_type} | Create data record | Yes |
| GET | /{id}/data/{record_type}/{record_id} | Get data record | Yes |
| PUT | /{id}/data/{record_type}/{record_id} | Update data record | Yes |
| DELETE | /{id}/data/{record_type}/{record_id} | Delete data record | Yes |
Plugin Marketplace
Prefix: /api/marketplace
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | Browse marketplace | No |
| GET | /info | Marketplace info | No |
| GET | /{id} | Get plugin details | No |
| POST | /registry | Register plugin in marketplace | Yes (admin) |
| GET | /tenant/installed | List tenant’s installed plugins | Yes |
| POST | /tenant/install | Install from marketplace | Yes |
| POST | /tenant/{id}/enable | Enable installed plugin | Yes |
| POST | /tenant/{id}/disable | Disable installed plugin | Yes |
| DELETE | /tenant/{id} | Uninstall marketplace plugin | Yes |
Search and Relationships
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /search | Search across entity types | Yes |
| GET | /search/all | Full-text search all entities | Yes |
| GET | /recent | Recently updated entities | Yes |
| GET | /relationships/{type}/{id} | Get entity relationships | Yes |
| GET | /graph/universe | Get full entity relationship graph | Yes |
| GET | /graph/entity/{type}/{id} | Get entity-centric subgraph | Yes |
Cross-References and Context
Prefix: /api/entity
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /cross-reference/query | Query cross-references | Yes |
| POST | /cross-reference/context | Build cross-reference context | Yes |
| POST | /cross-reference/romance | Find romantic connections | Yes |
| POST | /cross-reference/faction-war | Find faction conflicts | Yes |
| GET | /cross-reference/validate/{type}/{id} | Validate references | Yes |
| POST | /hybrid-relationships | Discover hybrid relationships | Yes |
| POST | /semantic-connections | Find semantic connections via embeddings | Yes |
| POST | /structured-relationships | Structured relationship query | Yes |
| POST | /enhanced-context | Build enhanced entity context for AI | Yes |
Layouts
Prefix: /api/layouts
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | List all layout definitions | No |
| GET | /{type} | Get layout for entity type | No |
| PUT | /{type} | Update layout for entity type | Yes |
| POST | /{type}/reset | Reset layout to defaults | Yes |
| DELETE | /{type} | Delete custom layout | Yes |
Timeline
Prefix: /api/timeline
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | List timeline events with filtering | Yes |
| POST | /auto-populate | Auto-populate timeline from entity data | Yes |
| GET | /conflicts | Find timeline conflicts | Yes |
| POST | /export | Export timeline data | Yes |
Assembly System
Prefix: /api/assembly
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /{id}/slots | List assembly slots | Yes |
| GET | /{id}/slots/{group} | Get slots by group | Yes |
| POST | /{id}/slots | Add slot to assembly | Yes |
| DELETE | /{id}/slots/{group}/{name} | Remove slot | Yes |
| PUT | /{id}/slots/reorder | Reorder slots | Yes |
| PUT | /{id}/slots/{group}/{name}/transform | Transform slot | Yes |
| POST | /{id}/parent | Set parent assembly | Yes |
| DELETE | /{id}/parent | Remove parent | Yes |
| GET | /{id}/inheritance | Get inheritance chain | Yes |
| POST | /{id}/slots/lock | Lock slots | Yes |
| POST | /{id}/slots/unlock | Unlock slots | Yes |
| GET | /{id}/zombie/{stage} | Get zombie stage data | Yes |
| POST | /{id}/zombie/validate | Validate zombie assembly | Yes |
| GET | /export/profiles | List export profiles | Yes |
| POST | /{id}/export/{profile} | Export assembly | Yes |
| GET | /{id}/manifest/{profile} | Get export manifest | Yes |
| POST | /{id}/validate | Validate assembly | Yes |
| GET | /{id}/validate/status | Validation status | Yes |
| GET | /{id}/completeness | Check assembly completeness | Yes |
| GET | /{id}/preview | Preview assembly | Yes |
| GET | /by-asset/{asset_id} | Find assemblies using asset | Yes |
| POST | /auto-detect-slot | Auto-detect slot type for asset | Yes |
| GET | /template/types | List assembly template types | Yes |
| GET | /template/slot-definitions | Get slot definitions | Yes |
| POST | /export/profiles/reload | Reload export profiles | Yes |
Recycle Bin
Prefix: /api
Entities
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /recycle-bin/entity | List recycled entities | Yes |
| POST | /recycle-bin/entity/{type}/{id}/restore | Restore entity | Yes |
| DELETE | /recycle-bin/entity/{type}/{id}/permanent | Permanently delete | Yes (admin) |
| POST | /recycle-bin/entity/empty | Empty entity recycle bin | Yes (admin) |
Assets
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /recycle-bin | List recycled assets | Yes |
| POST | /recycle-bin/{id}/restore | Restore asset | Yes |
| DELETE | /recycle-bin/{id}/permanent | Permanently delete asset | Yes (admin) |
| POST | /recycle-bin/empty | Empty asset recycle bin | Yes (admin) |
| POST | /recycle-bin/auto-cleanup | Auto-cleanup old items | Yes (admin) |
Services and Health
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /health | Basic health check | No |
| GET | /api/health | Basic health check (prefixed) | No |
| GET | /health/detailed | Detailed health with DB status | No |
| GET | /api/check-entity-id/{id} | Check if entity ID is available | No |
| GET | /api/services/status | Service status (backend, AI, DB) | Yes |
| POST | /api/services/restart/{service} | Restart a service | Yes (admin) |
| POST | /api/services/terminate/ai | Terminate AI service | Yes (admin) |
| GET | /api/services/logs/{service} | Get service logs | Yes |
| POST | /api/services/logs/{service}/clear | Clear service logs | Yes (admin) |
| GET | /api/services/logs/list | List available log files | Yes |
| POST | /api/logs/frontend | Submit frontend log entries | No |
WebSocket
Endpoint: ws://host:8201/api/ws
Connect with a JWT token as a query parameter or in the first message. The WebSocket channel provides real-time events:
| Event | Description |
|---|---|
entity_updated | Entity was created, updated, or deleted |
sync_completed | Markdown sync finished |
presence_update | User came online/offline/started editing |
brainbits_deducted | BrainBits consumed for AI operation |
asset_processed | Asset analysis completed |
Presence
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /api/presence | Get online users | Yes |
| GET | /api/presence/editing | Get who is editing what | Yes |
StudioBrain Cloud scopes presence by tenant. The cloud API uses
/api/presence/{tenant_id}paths for tenant-isolated presence tracking.
Settings
Prefix: /api/settings
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | Get user settings | Yes |
| PUT | “ | Update user settings | Yes |
| GET | /keys | List configured AI provider keys | Yes |
| PUT | /keys/{provider} | Set AI provider key | Yes |
| DELETE | /keys/{provider} | Remove AI provider key | Yes |
Feature Gates
Prefix: /api/features
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | Get enabled features for current tier | Yes |
| GET | /tiers | List all tiers and their features | No |
Groups and Quotas
Groups
Prefix: /api/groups
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /presets | List group presets | Yes |
| GET | /user/{user_id} | Get user’s groups | Yes |
| POST | “ | Create group | Yes (admin) |
| GET | “ | List groups | Yes |
| GET | /{id} | Get group | Yes |
| PUT | /{id} | Update group | Yes (admin) |
| DELETE | /{id} | Delete group | Yes (admin) |
| POST | /{id}/members | Add member to group | Yes (admin) |
| DELETE | /{id}/members/{user_id} | Remove member | Yes (admin) |
Quota Groups
Prefix: /api/quota-groups
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | / | List quota groups | Yes |
| PUT | /{id}/quota | Update group quota | Yes (admin) |
| GET | /{id}/usage | Get group usage | Yes |
| POST | /{id}/reset | Reset group usage counters | Yes (admin) |
Sharing
Prefix: (none, uses full paths)
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /api/shares | Create share link | Yes |
| GET | /api/shares | List shares | Yes |
| DELETE | /api/shares/{id} | Delete share | Yes |
| GET | /api/share/{code} | Access shared content | No |
| GET | /api/share/{code}/entities/{type} | List entities in share | No |
Database Admin
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /database/test | Test database connection | Yes |
| GET | /database/tables | List database tables | Yes (admin) |
| GET | /database/tables/{name}/data | View table data | Yes (admin) |
| POST | /database/query | Execute read-only SQL query | Yes (admin) |
| GET | /database/statistics | Database statistics | Yes |
| GET | /database/entities | Entity count by type | Yes |
| POST | /database/export | Export database | Yes (admin) |
| POST | /database/import | Import database | Yes (admin) |
| POST | /database/backup | Create database backup | Yes (admin) |
AI (Backend-Proxied)
These backend endpoints proxy specific AI operations. Most AI operations go directly to the AI service on port 8202.
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /image/styles/{type} | Get image generation styles for entity type | Yes |
| POST | /generate/character | Generate character via AI | Yes |
| POST | /enhance/character/{id} | Enhance existing character | Yes |
| POST | /generate/dialogue/{id} | Generate dialogue for character | Yes |
Image Presets
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /presets | List image generation presets | Yes |
| POST | /presets | Create preset | Yes |
| GET | /presets/{id} | Get preset | Yes |
| PUT | /presets/{id} | Update preset | Yes |
| DELETE | /presets/{id} | Delete preset | Yes |
Context Profiles
Prefix: /api/context-profiles
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | “ | List context profiles | Yes |
| POST | “ | Create context profile | Yes |
| GET | /{id} | Get context profile | Yes |
| PUT | /{id} | Update context profile | Yes |
| DELETE | /{id} | Delete context profile | Yes |
| POST | /{id}/resolve | Resolve profile (expand entity refs) | Yes |
Prompt Templates
Prefix: /api/prompt-templates
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /resolve | Resolve template variables | Yes |
| POST | /resolve-batch | Batch resolve templates | Yes |
| GET | /available-fields/{type} | List available template fields | Yes |
Inventory
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /items | List inventory items | Yes |
| GET | /items/categories | List item categories | Yes |
| GET | /items/{id} | Get item details | Yes |
| POST | /items | Create item | Yes |
| PUT | /items/{id} | Update item | Yes |
| DELETE | /items/{id} | Delete item | Yes |
| POST | /items/import/verse | Import items from Verse format | Yes |
| POST | /items/import/json | Import items from JSON | Yes |
| GET | /items/export/json | Export items as JSON | Yes |
| GET | /items/export/verse | Export items as Verse | Yes |
Migration and Archive
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| POST | /migration/import | Import full data export | Yes (admin) |
| GET | /migration/export | Export all data | Yes (admin) |
| GET | /archive/fallbacks | List archived fallback data | Yes |
| POST | /archive/fallbacks/restore | Restore from archive | Yes |
| POST | /archive/fallbacks/cleanup | Cleanup old archives | Yes (admin) |
Statistics and Activity
Prefix: /api
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /stats/dashboard | Dashboard statistics | Yes |
| GET | /activity/recent | Recent activity feed | Yes |
| GET | /activity/history | Full activity history | Yes |
Document Export
Prefix: /api/export
The Export System provides endpoints for exporting entities to HTML, PDF, and DOCX formats. See Export System Architecture for implementation details.
Endpoint Summary
| Method | Path | Description | Auth |
|---|---|---|---|
| GET | /export/layouts | List available export layout templates | Yes |
| POST | /export/{entity_type}/{entity_id}/html | Export entity to HTML | Yes |
| POST | /export/{entity_type}/{entity_id}/pdf | Export entity to PDF | Yes |
| POST | /export/{entity_type}/{entity_id}/docx | Export entity to DOCX | Yes |
| GET | /export/{entity_type}/{entity_id}/formats | Get available formats for entity | Yes |
Supported Formats
| Format | MIME Type | Extension | Features |
|---|---|---|---|
| HTML | text/html | .html | Embedded CSS, responsive, browser-printable |
application/pdf | .pdf | A4 size, cover page, TOC, print-optimized | |
| DOCX | application/vnd.openxmlformats-officedocument.wordprocessingml.document | .docx | Cover page, TOC, editable, professional styles |
Layout Templates
| Layout | Description | Use Case |
|---|---|---|
gdd_standard | Game Design Document format | Standard character/location documentation |
script_format | Screenplay/script format | Dialogue-heavy character sheets |
style_guide | Visual style guide format | Brands, visual references |
Export Endpoint Details
GET /api/export/layouts — Returns all available layout templates and their features.
POST /api/export/{entity_type}/{entity_id}/html
Query parameters: layout (default: gdd_standard), theme (default: default), embed_images (default: true).
Response: 200 OK with Content-Type: text/html. Body is a complete standalone HTML document with embedded CSS.
POST /api/export/{entity_type}/{entity_id}/pdf
Generates PDF via Playwright headless browser. Requires playwright install. Returns 503 Service Unavailable if Playwright is not installed.
Response: 200 OK with Content-Type: application/pdf. A4 format, 20mm margins, cover page + TOC.
POST /api/export/{entity_type}/{entity_id}/docx
Generates Word document via python-docx. Requires pip install python-docx. Returns 503 Service Unavailable if python-docx is not installed.
Response: 200 OK with DOCX MIME type. Includes cover page, table of contents, and styled content sections.
GET /api/export/{entity_type}/{entity_id}/formats
Returns available formats, their features, and requirements for the specified entity.
Error Responses
| Status | Condition |
|---|---|
404 Not Found | Entity does not exist |
503 Service Unavailable | PDF/DOCX dependency not installed |
429 Too Many Requests | Rate limit exceeded (10 requests/minute per user) |
500 Internal Server Error | Export generation failed |
For full endpoint details, request/response schemas, field mapping, and template variable reference, see Export API Reference or the interactive Swagger docs at /docs.
Support (Proprietary)
Prefix: /api/support
Access: Team+ and Enterprise cloud users only (feature-gated via priority_support)
Endpoints for requesting live co-browsing support via OpenReplay Assist. Notifications are sent to Discord webhook.
Status: SBAI-1207 (Phase O: Product Observability)
Endpoints
| Method | Path | Description | Auth | Feature Gate |
|---|---|---|---|---|
| GET | /status | Get support system status and configuration | Yes | priority_support |
| POST | /request-help | Request live co-browsing support | Yes | priority_support |
GET /api/support/status
Returns the support system health and OpenReplay configuration.
Response:
{
"support_enabled": true,
"openreplay_url": "https://replay.braindead.games",
"description": "Live support via OpenReplay Assist"
}Field Descriptions:
| Field | Type | Description |
|---|---|---|
support_enabled | boolean | Whether support requests are accepted |
openreplay_url | string | OpenReplay instance URL for assist links |
description | string | Human-readable support description |
POST /api/support/request-help
Request live support from the studio team. Creates a Discord notification and generates an OpenReplay Assist link.
Headers:
Authorization: Bearer {jwt_token}
Content-Type: application/jsonRequest Body:
{
"session_id": "sess_abc123xyz",
"assist_link": "https://replay.braindead.games/assist/sess_abc123xyz",
"plan": "team"
}Request Fields:
| Field | Type | Required | Description |
|---|---|---|---|
session_id | string | Yes | OpenReplay session identifier |
assist_link | string | Yes | Full OpenReplay Assist URL |
plan | string | No | User’s plan name (auto-detected from token) |
Response (200 OK):
{
"success": true,
"message": "Support request received",
"request_id": "req_20260312_001",
"assist_link": "https://replay.braindead.games/assist/sess_abc123xyz"
}Response Fields:
| Field | Type | Description |
|---|---|---|
success | boolean | Whether request was processed |
message | string | Human-readable status message |
request_id | string | Unique identifier for the support request |
assist_link | string | OpenReplay Assist link for session control |
Error Responses:
| Status | Error | Description |
|---|---|---|
401 | Unauthorized | Missing or invalid JWT token |
403 | Forbidden | Feature gate check failed (not Team+/Enterprise plan) |
422 | ValidationError | Request body validation failed |
500 | InternalError | Discord webhook delivery failed |
Discord Webhook Integration
When a support request is received, the backend sends an embedded notification to the #studio-support Discord channel.
Webhook Configuration:
- Environment variable:
DISCORD_SUPPORT_WEBHOOK - Format: Discord webhook URL (HTTPS)
- Embed includes: user email, tenant ID, session ID, plan, and assist link
Sample Embed:
{
"embeds": [{
"title": "Live Support Request",
"color": 5666194,
"fields": [
{"name": "User", "value": "user@example.com", "inline": true},
{"name": "Tenant", "value": "tenant_id", "inline": true},
{"name": "Session ID", "value": "sess_abc123", "inline": true},
{"name": "Plan", "value": "team", "inline": true},
{"name": "Assist Link", "value": "[Open Assist →]https://replay.braindead.games/assist/sess_abc123", "inline": false}
],
"footer": {"text": "StudioBrain Support System"},
"timestamp": "2026-03-12T23:30:00Z"
}]
}Feature Gate Configuration
Support access is controlled by the priority_support feature gate defined in config/plans.py:
PLAN_DEFINITIONS = {
"free": {"priority_support": False},
"indie": {"priority_support": False},
"team": {"priority_support": True},
"enterprise": {"priority_support": True},
}Implementation Reference
- Frontend Component:
city-brains-studio/src/components/support/LiveHelpButton.tsx - Backend Routes:
CityBrainsStoryBuilder/backend/routes/support_routes.py - Route Registration:
CityBrainsStoryBuilder/backend/main.py(cloud mode only) - Full Documentation: Co-Browsing Support Guide
Related Documentation
- OpenReplay Deployment - Infrastructure setup
- Plans Configuration - Feature gate definitions