API Reference
The PopcornTeam REST API surface, generated from the OpenAPI 3.1 spec. 80 operations across 13 resource groups.
This page is generated from the OpenAPI 3.1 specification at src/lib/openapi. The live machine-readable spec is served at GET /api/v1/openapi. There are 80 operations across 13 resource groups.
Base URL
https://admin.example.com
Authentication
Every endpoint requires authentication. Two mechanisms are accepted:
- Session cookie (
admin-session) — Firebase Auth session for browser/dashboard callers. - API key —
Authorization: Bearer <key>for programmatic callers. See Authentication for scopes.
Auth
Authentication and session management
| Method | Path | Summary |
|---|---|---|
DELETE | /api/v1/auth/session | Logout |
GET | /api/v1/auth/session | Verify session |
POST | /api/v1/auth/session | Create session cookie |
Agents
Agent CRUD, configuration, and status
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/agents | List all agents |
POST | /api/v1/agents | Create agent |
DELETE | /api/v1/agents/{id} | Delete agent (soft) |
GET | /api/v1/agents/{id} | Get agent |
PATCH | /api/v1/agents/{id} | Update agent |
GET | /api/v1/agents/health | System health |
GET | /api/v1/agents/memory | List memories |
POST | /api/v1/agents/memory | Create memory |
GET | /api/v1/agents/models | List Claude models |
GET | /api/v1/agents/tools | List tool categories |
POST /api/v1/agents
Create agent
Request body (application/json)
{
"type": "object",
"properties": {
"name": {
"type": "string"
},
"displayName": {
"type": "string"
},
"identity": {
"$ref": "#/components/schemas/AgentIdentityInput"
}
},
"required": ["name", "displayName"]
}DELETE /api/v1/agents/{id}
Delete agent (soft)
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/v1/agents/{id}
Get agent
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PATCH /api/v1/agents/{id}
Update agent
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Request body (application/json)
{
"type": "object",
"properties": {
"identity": {
"$ref": "#/components/schemas/AgentIdentityInput"
}
}
}Skills
Skill management for agents
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/agents/skills | List skills |
POST | /api/v1/agents/skills | Create skill |
DELETE | /api/v1/agents/skills/{id} | Delete skill |
GET | /api/v1/agents/skills/{id} | Get skill |
PATCH | /api/v1/agents/skills/{id} | Update skill |
DELETE /api/v1/agents/skills/{id}
Delete skill
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/v1/agents/skills/{id}
Get skill
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PATCH /api/v1/agents/skills/{id}
Update skill
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Flows
Automation flow configuration and execution
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/agents/flows | List flows |
POST | /api/v1/agents/flows | Create flow |
DELETE | /api/v1/agents/flows/{id} | Delete flow |
GET | /api/v1/agents/flows/{id} | Get flow |
PATCH | /api/v1/agents/flows/{id} | Update flow |
POST | /api/v1/agents/flows/{id}/trigger | Trigger flow |
DELETE /api/v1/agents/flows/{id}
Delete flow
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/v1/agents/flows/{id}
Get flow
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PATCH /api/v1/agents/flows/{id}
Update flow
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
POST /api/v1/agents/flows/{id}/trigger
Trigger flow
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Threads
Conversation threads and messages
| Method | Path | Summary |
|---|---|---|
POST | /api/v1/chat | Send chat message |
GET | /api/v1/threads | List threads |
POST | /api/v1/threads | Create thread |
DELETE | /api/v1/threads/{id} | Delete thread |
GET | /api/v1/threads/{id} | Get thread |
PATCH | /api/v1/threads/{id} | Update thread |
DELETE | /api/v1/threads/{id}/access | Remove thread access entries |
GET | /api/v1/threads/{id}/access | Get thread access state |
PATCH | /api/v1/threads/{id}/access | Update thread access settings |
POST | /api/v1/threads/{id}/access | Create thread access entries |
POST | /api/v1/threads/{id}/fork | Fork thread |
GET | /api/v1/threads/{id}/messages | Get messages |
GET | /api/v1/threads/stats | Thread stats |
GET /api/v1/threads
List threads
Parameters
| Name | In | Required | Type |
|---|---|---|---|
status | query | no | string |
source | query | no | string |
limit | query | no | integer |
DELETE /api/v1/threads/{id}
Delete thread
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/v1/threads/{id}
Get thread
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PATCH /api/v1/threads/{id}
Update thread
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
DELETE /api/v1/threads/{id}/access
Remove thread access entries
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/v1/threads/{id}/access
Get thread access state
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PATCH /api/v1/threads/{id}/access
Update thread access settings
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
POST /api/v1/threads/{id}/access
Create thread access entries
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
POST /api/v1/threads/{id}/fork
Fork thread
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/v1/threads/{id}/messages
Get messages
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PopcornTeam Users
Admin user management (Firestore)
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/popcornteam-users | List admin users |
POST | /api/v1/popcornteam-users | Create admin user |
GET | /api/v1/popcornteam-users/{id} | Get admin user |
POST | /api/v1/popcornteam-users/{id}/deactivate | Deactivate |
POST | /api/v1/popcornteam-users/{id}/reactivate | Reactivate |
GET /api/v1/popcornteam-users/{id}
Get admin user
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
POST /api/v1/popcornteam-users/{id}/deactivate
Deactivate
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
POST /api/v1/popcornteam-users/{id}/reactivate
Reactivate
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Analytics
Overview, traffic, revenue, and product analytics
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/analytics/insights | AI insights |
GET | /api/v1/analytics/overview | Overview metrics |
GET | /api/v1/analytics/product/active-users | Active users |
GET | /api/v1/analytics/product/cohort-retention | Cohort retention |
GET | /api/v1/analytics/product/feature-adoption | Feature adoption |
GET | /api/v1/analytics/product/onboarding-funnel | Onboarding funnel |
GET | /api/v1/analytics/product/website-states | Website states |
GET | /api/v1/analytics/revenue/churn | Churn data |
GET | /api/v1/analytics/revenue/ltv | LTV data |
GET | /api/v1/analytics/revenue/mrr | MRR data |
GET | /api/v1/analytics/revenue/subscriptions | Subscriptions |
GET | /api/v1/analytics/traffic/channels | Traffic by channel |
GET | /api/v1/analytics/traffic/geography | Geographic traffic |
GET | /api/v1/analytics/traffic/technology | Technology breakdown |
GET | /api/v1/analytics/traffic/visitors | Visitor traffic |
Reports
Report creation and management
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/reports | List reports |
POST | /api/v1/reports | Create report |
DELETE | /api/v1/reports/{id} | Delete report |
GET | /api/v1/reports/{id} | Get report |
PATCH | /api/v1/reports/{id} | Update report |
DELETE /api/v1/reports/{id}
Delete report
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/v1/reports/{id}
Get report
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PATCH /api/v1/reports/{id}
Update report
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Settings
Bot configuration and admin settings
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/bot-config | Get bot config |
PUT | /api/v1/bot-config | Update bot config |
GET | /api/v1/settings | Admin settings |
PATCH | /api/v1/settings | Update settings |
PUT /api/v1/bot-config
Update bot config
Request body (application/json)
{
"$ref": "#/components/schemas/BotConfigUpdate"
}System
Health checks and system status
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/health | Health check |
GET | /api/v1/search | Global search |
GET /api/v1/search
Global search
Parameters
| Name | In | Required | Type |
|---|---|---|---|
q | query | yes | string |
MCP
PopcornTeam unified MCP endpoint — JSON-RPC 2.0 over HTTP, api-key authenticated. One URL serves every resource type (integration tools, agents, flows, projects, tasks, goals, documents, artifacts, memory) with caller-visibility gated by api-key grants.
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/mcp | Endpoint health stub |
POST | /api/v1/mcp | PopcornTeam unified MCP endpoint — JSON-RPC 2.0 |
POST /api/v1/mcp
PopcornTeam unified MCP endpoint — JSON-RPC 2.0
Request body (application/json)
{
"type": "object",
"required": ["jsonrpc", "method"],
"properties": {
"jsonrpc": {
"type": "string",
"enum": ["2.0"]
},
"id": {
"description": "Request id. Omit for notifications.",
"oneOf": [
{
"type": "string"
},
{
"type": "integer"
}
]
},
"method": {
"type": "string",
"enum": ["initialize", "tools/list", "tools/call"]
},
"params": {
"type": "object"
}
}
}Capsules
Named bundles of allowed tools exposed as bearer-authenticated MCP endpoints for BYO-LLM clients (Claude Desktop, Cursor, custom code). PopcornTeam provides auth + audit; the client provides the model.
| Method | Path | Summary |
|---|---|---|
GET | /api/capsules | List capsules |
POST | /api/capsules | Create a capsule |
DELETE | /api/capsules/{id} | Delete a capsule |
GET | /api/capsules/{id} | Get a capsule |
PATCH | /api/capsules/{id} | Update a capsule |
POST | /api/capsules/{id}/rotate-token | Rotate the bearer token |
POST /api/capsules
Create a capsule
Request body (application/json)
{
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string",
"maxLength": 120
},
"description": {
"type": "string",
"maxLength": 2000
},
"allowedTools": {
"type": "array",
"items": {
"type": "string"
}
},
"deniedTools": {
"type": "array",
"items": {
"type": "string"
}
},
"status": {
"type": "string",
"enum": ["draft", "live", "disabled"]
}
}
}DELETE /api/capsules/{id}
Delete a capsule
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
GET /api/capsules/{id}
Get a capsule
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
PATCH /api/capsules/{id}
Update a capsule
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
POST /api/capsules/{id}/rotate-token
Rotate the bearer token
Parameters
| Name | In | Required | Type |
|---|---|---|---|
id | path | yes | string |
Versions
Generic version history, diff, and restore surfaces for versioned PopcornTeam entities.
| Method | Path | Summary |
|---|---|---|
GET | /api/v1/versions/{entityType}/{entityId} | List versions for an entity |
GET | /api/v1/versions/{entityType}/{entityId}/{versionId} | Get a version |
GET | /api/v1/versions/{entityType}/{entityId}/{versionId}/diff | Diff a version |
POST | /api/v1/versions/{entityType}/{entityId}/{versionId}/restore | Restore an entity to a version |
GET /api/v1/versions/{entityType}/{entityId}
List versions for an entity
Parameters
| Name | In | Required | Type |
|---|---|---|---|
entityType | path | yes | string |
entityId | path | yes | string |
GET /api/v1/versions/{entityType}/{entityId}/{versionId}
Get a version
Parameters
| Name | In | Required | Type |
|---|---|---|---|
entityType | path | yes | string |
entityId | path | yes | string |
versionId | path | yes | string |
GET /api/v1/versions/{entityType}/{entityId}/{versionId}/diff
Diff a version
Parameters
| Name | In | Required | Type |
|---|---|---|---|
entityType | path | yes | string |
entityId | path | yes | string |
versionId | path | yes | string |
against | query | no |
POST /api/v1/versions/{entityType}/{entityId}/{versionId}/restore
Restore an entity to a version
Parameters
| Name | In | Required | Type |
|---|---|---|---|
entityType | path | yes | string |
entityId | path | yes | string |
versionId | path | yes | string |
Request body (application/json)
{
"type": "object",
"properties": {
"expectedRevision": {
"type": "integer",
"description": "Latest revision expected by the caller. When supplied, stale restores fail with 409."
}
}
}Schemas
Shared response/request object shapes referenced above (#/components/schemas/...):
Agent
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"displayName": {
"type": "string"
},
"description": {
"type": "string"
},
"modelPreference": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["active", "paused", "deleted"]
},
"tools": {
"type": "array",
"items": {
"type": "string"
}
},
"identity": {
"$ref": "#/components/schemas/AgentIdentity"
},
"createdAt": {
"type": "string",
"format": "date-time"
}
},
"required": ["id", "name", "displayName", "status"]
}AgentIdentity
{
"type": "object",
"description": "Per-agent persona and channel facade. Phone numbers and card references are masked in responses.",
"properties": {
"displayName": {
"type": "string"
},
"avatarUrl": {
"type": "string"
},
"bio": {
"type": "string"
},
"signature": {
"type": "string"
},
"mailingAddress": {
"type": "object",
"properties": {
"line1": {
"type": "string"
},
"line2": {
"type": "string"
},
"city": {
"type": "string"
},
"region": {
"type": "string"
},
"postalCode": {
"type": "string"
},
"country": {
"type": "string"
}
}
},
"socials": {
"type": "array",
"items": {
"type": "object",
"properties": {
"platform": {
"type": "string"
},
"url": {
"type": "string"
}
},
"required": ["platform", "url"]
}
},
"email": {
"type": "object",
"properties": {
"alias": {
"type": "string"
}
}
},
"phone": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"number": {
"type": "string",
"description": "Masked with ••• when provisioned."
},
"provider": {
"type": "string",
"enum": ["twilio"]
},
"a2pStatus": {
"type": "string",
"enum": ["unregistered", "pending", "registered"]
}
},
"required": ["enabled"]
},
"card": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"railId": {
"type": "string",
"enum": ["stripe-issuing", "agentcard", "cf-wallet"]
},
"cardRef": {
"type": "string",
"description": "Masked with ••• when provisioned."
},
"spendLimitUsd": {
"type": "number",
"minimum": 0
}
},
"required": ["enabled"]
},
"voice": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"mode": {
"type": "string",
"enum": ["browser", "phone"]
},
"ttsProvider": {
"type": "string"
}
},
"required": ["enabled"]
},
"cfPayHandle": {
"type": "string",
"description": "Public permanent cloudflare.pay agent-ID wallet handle."
}
}
}AgentIdentityInput
{
"type": "object",
"properties": {
"displayName": {
"type": "string"
},
"avatarUrl": {
"type": "string"
},
"bio": {
"type": "string"
},
"signature": {
"type": "string"
},
"mailingAddress": {
"type": "object",
"properties": {
"line1": {
"type": "string"
},
"line2": {
"type": "string"
},
"city": {
"type": "string"
},
"region": {
"type": "string"
},
"postalCode": {
"type": "string"
},
"country": {
"type": "string"
}
}
},
"socials": {
"maxItems": 20,
"type": "array",
"items": {
"type": "object",
"properties": {
"platform": {
"type": "string"
},
"url": {
"type": "string"
}
},
"required": ["platform", "url"]
}
},
"email": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"alias": {
"type": "string",
"minLength": 1
}
}
},
"phone": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"provider": {
"type": "string",
"enum": ["twilio"]
}
},
"required": ["enabled"]
},
"voice": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"mode": {
"type": "string",
"enum": ["browser", "phone"]
},
"ttsProvider": {
"type": "string"
}
},
"required": ["enabled"]
},
"card": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"railId": {
"type": "string",
"enum": ["stripe-issuing", "agentcard", "cf-wallet"]
},
"spendLimitUsd": {
"type": "number",
"minimum": 0
}
},
"required": ["enabled"]
},
"postal": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean"
},
"provider": {
"type": "string"
}
},
"required": ["enabled"]
},
"cfPayHandle": {
"type": "string"
}
},
"description": "Client-writable agent identity fields. Phone numbers, card references, and A2P status are server-managed."
}BotConfig
{
"type": "object",
"properties": {
"systemPrompt": {
"type": "string"
},
"promptConfigVersion": {
"type": "integer"
},
"promptSections": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"defaultModel": {
"type": "string"
},
"maxTokens": {
"type": "integer"
}
}
}BotConfigUpdate
{
"type": "object",
"description": "Update the bot config. promptSections is the writable source of truth for prompt editing. The response still includes the composed systemPrompt for read-only inspection.",
"properties": {
"promptSections": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"defaultModel": {
"type": "string"
},
"maxTokens": {
"type": "integer",
"minimum": 1024,
"maximum": 32768
}
}
}Error
{
"type": "object",
"properties": {
"error": {
"type": "string"
}
},
"required": ["error"]
}Flow
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"agentId": {
"type": "string"
},
"enabled": {
"type": "boolean"
}
},
"required": ["id", "name"]
}Message
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"role": {
"type": "string"
},
"content": {
"type": "string"
}
},
"required": ["id", "role", "content"]
}OverviewMetrics
{
"type": "object",
"properties": {
"totalUsers": {
"type": "integer"
},
"mrr": {
"type": "number"
},
"churnRate": {
"type": "number"
}
}
}PopcornTeamUser
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"email": {
"type": "string"
},
"role": {
"type": "string"
},
"isActive": {
"type": "boolean"
}
},
"required": ["id", "email", "role"]
}Report
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
}
},
"required": ["id", "title"]
}Skill
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"displayName": {
"type": "string"
},
"instructions": {
"type": "string"
}
},
"required": ["id", "name"]
}SystemHealth
{
"type": "object",
"properties": {
"overallStatus": {
"type": "string"
},
"integrations": {
"type": "array",
"items": {
"type": "object"
}
}
}
}Thread
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"title": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["active", "archived"]
},
"source": {
"type": "string"
},
"agentIds": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": ["id", "title", "status"]
}UserWithBilling
{
"type": "object",
"properties": {
"uid": {
"type": "string"
},
"email": {
"type": "string"
},
"status": {
"type": "string",
"enum": ["PRO", "FREE", "LEGACY"]
}
},
"required": ["uid", "email", "status"]
}Version
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"entityType": {
"type": "string",
"enum": [
"task-document",
"agent-config",
"agent",
"flow",
"skill",
"project",
"memory",
"artifact",
"database-record",
"document"
]
},
"entityId": {
"type": "string"
},
"revision": {
"type": "integer"
},
"content": {
"type": "string"
},
"contentHash": {
"type": "string"
},
"kind": {
"type": "string",
"enum": ["snapshot", "restore", "delete"]
},
"payload": {
"type": "object",
"additionalProperties": true
},
"author": {
"type": "object",
"properties": {
"type": {
"type": "string"
},
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": ["type", "id", "name"]
},
"createdAt": {
"type": "string",
"format": "date-time"
},
"changeDescription": {
"type": "string"
}
},
"required": [
"id",
"entityType",
"entityId",
"revision",
"content",
"contentHash",
"kind",
"author",
"createdAt"
]
}VersionDiff
{
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": ["text", "json"]
},
"lines": {
"type": "array",
"items": {
"type": "object",
"properties": {
"op": {
"type": "string",
"enum": ["equal", "add", "remove"]
},
"value": {
"type": "string"
}
},
"required": ["op", "value"]
}
},
"changes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"path": {
"type": "string"
},
"before": {},
"after": {}
},
"required": ["path"]
}
}
},
"required": ["kind"]
}Browser automation & QA (Browserbase)
How any PopcornTeam agent drives a real remote browser via the browser_* tools — navigate, observe, act, extract, screenshot — plus the captcha + residential-proxy setup, live-view, session reuse across HITL pauses, and how to point this at QA/verification (popcornteam-qa) not just directory submissions.
Agents
An agent is a Firestore-backed record that binds a persona, a model, a tool allowlist, and memory into something that can be invoked.