{"openapi":"3.1.0","info":{"title":"Forkline Public API","description":"Forkline Public API for programmatic access using Personal Access Tokens (PAT).\n\n## Authentication\n\nAll endpoints require a PAT passed as `Authorization: Bearer <token>`.\nTokens are scoped — each token grants only the permissions selected when creating it.\n\n## Scopes\n\n| Scope | Description |\n|-------|-------------|\n| `user:read` | Read user profile |\n| `repositories:read` | List and read repositories |\n| `repositories:write` | Create, update, delete repositories |\n| `runners:read` | List and read runners |\n| `runners:write` | Start, stop, and manage runners |\n| `runners:attach` | Obtain short-lived attach grants for running runners |\n| `models:read` | List AI models and providers |\n| `analytics:read` | Read usage analytics |\n| `routines:read` | List and read routines |\n| `routines:write` | Create, update, delete routines |\n| `routines:execute` | Run routines now |\n| `tokens:manage` | Manage personal API tokens |\n| `secrets:manage` | Manage repository secrets |\n| `providers:manage` | Manage custom AI providers |\n| `connectors:read` | List git connectors |\n| `billing:read` | Read billing and credit information |\n| `user:write` | Update user settings |","license":{"name":"Apache 2.0","url":"https://www.apache.org/licenses/LICENSE-2.0"},"version":"1.0.0"},"paths":{"/v1/analytics/history":{"get":{"tags":["analytics"],"operationId":"get_history","parameters":[{"name":"start","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}},{"name":"end","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsHistoryResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/analytics/models":{"get":{"tags":["analytics"],"operationId":"get_model_breakdown","parameters":[{"name":"start","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}},{"name":"end","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UsageBreakdownResponse"}}}}}},"security":[{"bearer_auth":[]}]}},"/v1/analytics/overview":{"get":{"tags":["analytics"],"operationId":"get_overview","parameters":[{"name":"start","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}},{"name":"end","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsOverviewResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/analytics/providers":{"get":{"tags":["analytics"],"operationId":"get_provider_breakdown","parameters":[{"name":"start","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}},{"name":"end","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UsageBreakdownResponse"}}}}}},"security":[{"bearer_auth":[]}]}},"/v1/analytics/repositories":{"get":{"tags":["analytics"],"operationId":"get_repository_breakdown","parameters":[{"name":"start","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}},{"name":"end","in":"path","required":true,"schema":{"type":["string","null"],"format":"date"}}],"responses":{"200":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UsageBreakdownResponse"}}}}}},"security":[{"bearer_auth":[]}]}},"/v1/billing/credits":{"get":{"tags":["billing"],"summary":"Response for credits endpoint.\nGet user's credit balance with breakdown.","operationId":"get_credits","responses":{"200":{"description":"Credit balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditsResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/connectors":{"get":{"tags":["connectors"],"summary":"List all connectors for the current user.","operationId":"list_connectors","parameters":[{"name":"include_deleted","in":"path","required":true,"schema":{"type":["boolean","null"]}}],"responses":{"200":{"description":"List of connectors","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListConnectorsResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/custom-providers":{"get":{"tags":["custom-providers"],"summary":"List all custom providers for the current user.","operationId":"list_custom_providers","responses":{"200":{"description":"List of custom providers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListCustomProvidersResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/custom-providers/import":{"post":{"tags":["custom-providers"],"summary":"Import a custom provider from OpenCode config format.","operationId":"import_custom_provider","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportCustomProviderRequest"}}},"required":true},"responses":{"201":{"description":"Custom provider imported","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomProvider"}}}},"400":{"description":"Invalid config"},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/custom-providers/{provider_id}":{"delete":{"tags":["custom-providers"],"summary":"Delete a custom provider.","operationId":"delete_custom_provider","responses":{"204":{"description":"Provider deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Provider not found"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-catalog":{"get":{"tags":["mcp"],"operationId":"list_mcp_catalog","parameters":[{"name":"q","in":"query","description":"Substring match against title, slug and canonical name. A non-empty search also\nreturns entries that are not available on Forkline, flagged `installable=false`.","required":false,"schema":{"type":"string"}},{"name":"after","in":"query","description":"Cursor: the `next_cursor` of the previous page, passed back unchanged.","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","description":"Page size, clamped to 1..=500.","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"MCP catalog entries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMcpCatalogResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-catalog/{id}":{"get":{"tags":["mcp"],"operationId":"get_mcp_catalog_entry","parameters":[{"name":"id","in":"path","description":"Catalog entry identifier (external_id or slug)","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Catalog entry with revisions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetMcpCatalogEntryResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Catalog entry not found"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-servers":{"get":{"tags":["mcp"],"summary":"`GET /mcp-servers`.","operationId":"list_mcp_servers","responses":{"200":{"description":"Your MCP servers, with their status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMcpServersResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]},"post":{"tags":["mcp"],"summary":"`POST /mcp-servers`.","operationId":"create_mcp_server","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateMcpServerRequest"}}},"required":true},"responses":{"201":{"description":"MCP server created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpServer"}}}},"400":{"description":"Invalid request; `issues` carries the failing fields"},"401":{"description":"Unauthorized"},"409":{"description":"Server ID already taken, or a stale `generation`"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-servers/parse":{"post":{"tags":["mcp"],"summary":"`POST /mcp-servers/parse`: stateless; pasted JSON from Claude Code, Cursor, VS Code or\nOpenCode to draft servers. A syntax error is a 400 with line and column.","operationId":"parse_mcp_servers","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseMcpServersRequest"}}},"required":true},"responses":{"200":{"description":"Draft servers found in the pasted JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseMcpServersResponse"}}}},"400":{"description":"The text is not valid JSON, or is too large"},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-servers/{id}":{"get":{"tags":["mcp"],"summary":"`GET /mcp-servers/{id}`.","operationId":"get_mcp_server","parameters":[{"name":"id","in":"path","description":"MCP server ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"One MCP server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpServer"}}}},"401":{"description":"Unauthorized"},"404":{"description":"MCP server not found"}},"security":[{"bearer_auth":[]}]},"delete":{"tags":["mcp"],"summary":"`DELETE /mcp-servers/{id}`: hard delete.","operationId":"delete_mcp_server","parameters":[{"name":"id","in":"path","description":"MCP server ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"MCP server deleted"},"401":{"description":"Unauthorized"},"404":{"description":"MCP server not found"}},"security":[{"bearer_auth":[]}]},"patch":{"tags":["mcp"],"summary":"`PATCH /mcp-servers/{id}`: one statement, so one transaction. `generation` is optional\noptimistic concurrency (409 when stale).","operationId":"update_mcp_server","parameters":[{"name":"id","in":"path","description":"MCP server ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMcpServerRequest"}}},"required":true},"responses":{"200":{"description":"Updated MCP server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpServer"}}}},"400":{"description":"Invalid request; `issues` carries the failing fields"},"401":{"description":"Unauthorized"},"404":{"description":"MCP server not found"},"409":{"description":"Server ID already taken, or a stale `generation`"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-servers/{id}/repositories":{"get":{"tags":["mcp"],"summary":"`GET /mcp-servers/{id}/repositories?offset&limit`: the repositories the selector reaches\n(same compile and match as dispatch) with the health for each, problems first.","operationId":"list_mcp_server_repositories","parameters":[{"name":"id","in":"path","description":"MCP server ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"offset","in":"query","description":"Rows to skip (default 0)","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"limit","in":"query","description":"Page size (default 50, max 200)","required":false,"schema":{"type":"integer","format":"int64"}}],"responses":{"200":{"description":"Repositories the server reaches, with its state on each","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpServerRepositoriesResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Public API token lacks `mcp:read` or `repositories:read`"},"404":{"description":"MCP server not found"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-servers/{id}/upgrade":{"post":{"tags":["mcp"],"summary":"`POST /mcp-servers/{id}/upgrade`.","operationId":"upgrade_mcp_server","parameters":[{"name":"id","in":"path","description":"MCP server ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeMcpServerRequest"}}},"required":true},"responses":{"200":{"description":"Server moved to the new version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpServer"}}}},"400":{"description":"Invalid request; `issues` carries the failing fields"},"401":{"description":"Unauthorized"},"404":{"description":"MCP server not found"}},"security":[{"bearer_auth":[]}]}},"/v1/mcp-servers/{id}/upgrade-preview":{"get":{"tags":["mcp"],"summary":"`GET /mcp-servers/{id}/upgrade-preview?version=`.","operationId":"upgrade_preview","parameters":[{"name":"id","in":"path","description":"MCP server ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"version","in":"query","description":"Target version","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current versus target version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpUpgradePreview"}}}},"400":{"description":"Invalid request; `issues` carries the failing fields"},"401":{"description":"Unauthorized"},"404":{"description":"MCP server not found"}},"security":[{"bearer_auth":[]}]}},"/v1/me":{"get":{"tags":["user"],"summary":"Get the current authenticated user.","operationId":"get_current_user","responses":{"200":{"description":"Current user info","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUserResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/me/api-tokens":{"get":{"tags":["api-tokens"],"operationId":"public_list_api_tokens","responses":{"200":{"description":"List of API tokens","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTokenListResponse"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}},"security":[{"bearer_auth":[]}]},"post":{"tags":["api-tokens"],"operationId":"public_create_api_token","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiTokenRequest"}}},"required":true},"responses":{"201":{"description":"Created API token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiTokenCreateResponse"}}}},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}},"security":[{"bearer_auth":[]}]}},"/v1/me/api-tokens/{token_id}":{"delete":{"tags":["api-tokens"],"operationId":"public_delete_api_token","responses":{"204":{"description":"Token revoked"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Token not found"}},"security":[{"bearer_auth":[]}]}},"/v1/me/secrets":{"get":{"tags":["user"],"operationId":"list_account_secrets","responses":{"200":{"description":"List of account secrets (metadata only, never values)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListAccountSecretsResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]},"post":{"tags":["user"],"operationId":"create_account_secret","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecretRequest"}}},"required":true},"responses":{"201":{"description":"Account secret created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSecret"}}}},"400":{"description":"Invalid secret name"},"401":{"description":"Unauthorized"},"409":{"description":"Secret with this name already exists"}},"security":[{"bearer_auth":[]}]}},"/v1/me/secrets/{name}":{"put":{"tags":["user"],"operationId":"upsert_account_secret","parameters":[{"name":"name","in":"path","description":"Secret name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpsertAccountSecretRequest"}}},"required":true},"responses":{"200":{"description":"Account secret created or rotated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSecret"}}}},"400":{"description":"Invalid secret name"},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]},"delete":{"tags":["user"],"operationId":"delete_account_secret","parameters":[{"name":"name","in":"path","description":"Secret name","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Account secret deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Secret not found"}},"security":[{"bearer_auth":[]}]},"patch":{"tags":["user"],"operationId":"update_account_secret_description","parameters":[{"name":"name","in":"path","description":"Secret name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAccountSecretDescriptionRequest"}}},"required":true},"responses":{"200":{"description":"Account secret metadata updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSecret"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Secret not found"}},"security":[{"bearer_auth":[]}]}},"/v1/me/settings":{"get":{"tags":["user"],"summary":"Get user settings.","operationId":"get_user_settings","responses":{"200":{"description":"User settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserSettingsResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]},"put":{"tags":["user"],"summary":"Update all user settings in a single atomic operation.","operationId":"update_user_settings","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateAllSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Updated user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUserResponse"}}}},"400":{"description":"Invalid settings value"},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/models":{"get":{"tags":["models"],"summary":"List available models for the current user.","description":"Returns models filtered by the user's configured providers:\n- Shows all models from providers configured in auth.json\n- Always shows free OpenCode Zen models\n- Shows paid OpenCode Zen models only if \"opencode\" is configured","operationId":"list_models","responses":{"200":{"description":"List of available models","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListModelsResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/models/providers":{"get":{"tags":["models"],"summary":"List all available providers from models.dev.","description":"This endpoint returns all providers regardless of user configuration,\nfor use in the provider selection UI.","operationId":"list_all_providers","responses":{"200":{"description":"List of all available providers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProvidersResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/providers/{provider_id}/icon":{"get":{"tags":["providers"],"summary":"Get a provider's icon.","description":"Returns the SVG icon for a provider, cached from models.dev.\nThe response is cached for 24 hours in the browser.","operationId":"get_provider_icon","parameters":[{"name":"provider_id","in":"path","description":"Provider ID","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"SVG icon","content":{"image/svg+xml":{}}},"404":{"description":"Provider icon not found"}}}},"/v1/repositories":{"get":{"tags":["repositories"],"operationId":"list_repositories","parameters":[{"name":"include_deleted","in":"path","required":true,"schema":{"type":["boolean","null"]}},{"name":"connector_id","in":"path","required":true,"schema":{"type":["string","null"],"format":"uuid"}},{"name":"offset","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"limit","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"q","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"active_only","in":"path","required":true,"schema":{"type":["boolean","null"]}},{"name":"status","in":"path","required":true,"schema":{"oneOf":[{"$ref":"#/components/schemas/RepositoryStatus"},{"type":"null"}]}},{"name":"sort","in":"path","required":true,"schema":{"oneOf":[{"$ref":"#/components/schemas/RepositorySort"},{"type":"null"}]}}],"responses":{"200":{"description":"List of repositories","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRepositoriesResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]},"post":{"tags":["repositories"],"operationId":"create_repository","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRepositoryRequest"}}},"required":true},"responses":{"201":{"description":"Repository created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Repository"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/repositories/{id}":{"get":{"tags":["repositories"],"operationId":"get_repository","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Repository details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Repository"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]},"put":{"tags":["repositories"],"operationId":"update_repository","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRepositoryRequest"}}},"required":true},"responses":{"200":{"description":"Updated repository","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Repository"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]},"delete":{"tags":["repositories"],"operationId":"delete_repository","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Repository deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]}},"/v1/repositories/{id}/mcp-servers":{"get":{"tags":["mcp"],"summary":"`GET /repositories/{id}/mcp-servers`: the effective view.","operationId":"effective_mcp_servers","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The servers that apply to this repository","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepositoryMcpServers"}}}},"401":{"description":"Unauthorized"},"403":{"description":"Public API token lacks `mcp:read` or `repositories:read`"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]}},"/v1/repositories/{id}/opencode-config":{"get":{"tags":["repositories"],"operationId":"get_repo_opencode_config","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Repository OpenCode configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpencodeConfigResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]},"put":{"tags":["repositories"],"operationId":"update_repo_opencode_config","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOpencodeConfigRequest"}}},"required":true},"responses":{"200":{"description":"Updated repository OpenCode configuration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpencodeConfigResponse"}}}},"400":{"description":"Invalid configuration"},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]},"delete":{"tags":["repositories"],"operationId":"delete_repo_opencode_config","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Configuration cleared"},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]}},"/v1/repositories/{id}/restore":{"post":{"tags":["repositories"],"operationId":"restore_repository","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Repository restored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Repository"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]}},"/v1/repositories/{id}/runners":{"get":{"tags":["runners"],"operationId":"list_runners_by_repository","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"page","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"per_page","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"sort_by","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"sort_order","in":"path","required":true,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"List of runners","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunnersResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]},"post":{"tags":["runners"],"operationId":"start_runner","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartRunnerRequest"}}},"required":true},"responses":{"201":{"description":"Runner created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Runner"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]}},"/v1/repositories/{id}/secrets":{"get":{"tags":["repositories"],"operationId":"list_secrets","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"List of secrets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListSecretsResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"}},"security":[{"bearer_auth":[]}]},"post":{"tags":["repositories"],"operationId":"create_secret","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSecretRequest"}}},"required":true},"responses":{"201":{"description":"Secret created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepositorySecret"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Repository not found"},"409":{"description":"Secret with this name already exists"}},"security":[{"bearer_auth":[]}]}},"/v1/repositories/{id}/secrets/{name}":{"put":{"tags":["repositories"],"operationId":"update_secret","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"name","in":"path","description":"Secret name","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSecretRequest"}}},"required":true},"responses":{"200":{"description":"Secret updated"},"401":{"description":"Unauthorized"},"404":{"description":"Repository or secret not found"}},"security":[{"bearer_auth":[]}]},"delete":{"tags":["repositories"],"operationId":"delete_secret","parameters":[{"name":"id","in":"path","description":"Repository ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"name","in":"path","description":"Secret name","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Secret deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Repository or secret not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines":{"get":{"tags":["routines"],"operationId":"list_routines","responses":{"200":{"description":"List of routines","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRoutinesResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]},"post":{"tags":["routines"],"operationId":"create_routine","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoutineRequest"}}},"required":true},"responses":{"200":{"description":"Routine created. For an `on.webhook` routine the response carries the signing secret, once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"409":{"description":"The owner has reached the routine limit, or already has a routine with this name"},"422":{"description":"The spec is invalid; `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/backtest":{"post":{"tags":["routines"],"operationId":"backtest_routine","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacktestRoutineRequest"}}},"required":true},"responses":{"200":{"description":"What the spec would have done with the owner's stored events of the last `days` days (event type, repository selection, filters, `when` and a template check): counts, the stage that filtered each event, rows with a reason, and a cost estimate. Event-key dedupe, concurrency, run limits and credits are not simulated. Nothing is written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacktestRoutineResponse"}}}},"400":{"description":"The body is not a valid request, `spec` is missing, or `days`, `limit`, `show` or `pin_event_id` is invalid"},"401":{"description":"Unauthorized"},"404":{"description":"`pin_event_id` is not one of the owner's events"},"413":{"description":"The body is larger than 256 KiB"},"422":{"description":"The spec or the name is invalid; `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"429":{"description":"More than 60 back-tests in a minute","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/drafts/from-event":{"post":{"tags":["routines"],"operationId":"draft_routine_from_event","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftFromEventRequest"}}},"required":true},"responses":{"200":{"description":"A valid v2 spec drafted from the event's facts (`facts` omitted applies the default-checked ones; `event` and `repository` are always applied), the provenance of its values as JSON pointers into the spec (`fromEvent`, `suggested`), the facts with `checked`, up to two suggestions to widen the repository selection to sibling repositories (with a 7-day back-test), a unique suggested name and the event's headline. `widen: true` applies the first suggestion. Nothing is written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftFromEventResponse"}}}},"400":{"description":"The body is not a valid request"},"401":{"description":"Unauthorized"},"404":{"description":"The event was not found"},"413":{"description":"The body is larger than 16 KiB"},"422":{"description":"A fact key is not one of the event's facts (`/facts/{i}`), the event is not a repository event (`/event_id`), or the drafted spec is invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"429":{"description":"More than 30 drafts in a minute","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/events":{"get":{"tags":["routines"],"operationId":"list_recent_events","parameters":[{"name":"repository_id","in":"query","description":"Only events of this repository id. Not together with `repository`.","required":false,"schema":{"type":"string"}},{"name":"repository","in":"query","description":"Only events of this repository, `owner/name`, compared case-insensitively. Not\ntogether with `repository_id`.","required":false,"schema":{"type":"string"}},{"name":"event","in":"query","description":"Comma list of event names (`pr.opened`, `push`, ...). Default: all.","required":false,"schema":{"type":"string"}},{"name":"source","in":"query","description":"Comma list of `event`, `schedule`, `webhook`, `manual`. Default `event`. The others\nexist only when a routine ran.","required":false,"schema":{"type":"string"}},{"name":"reacted","in":"query","description":"`any` (default), `none` (no routine considered the event) or `some` (at least one\nrun record references it).","required":false,"schema":{"type":"string"}},{"name":"days","in":"query","description":"How many days back, 1 to 7. Default 7.","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"limit","in":"query","description":"Page size, 1 to 200. Default 50.","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"cursor","in":"query","description":"The `next_cursor` of the previous page.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"The owner's recent events (7 days), newest first, each with its newest reactions (routine runs that considered it). `older_dropped` is true when the per-owner cap of 5,000 events evicted older events inside the window.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRecentEventsResponse"}}}},"400":{"description":"A parameter or the cursor is invalid"},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/events/{event_id}":{"get":{"tags":["routines"],"operationId":"get_recent_event","parameters":[{"name":"event_id","in":"path","description":"Event ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"The event with up to 50 reactions and its facts: the properties a new routine can filter on, each with the spec fragment that checking it adds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecentEventDetail"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Event not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/test":{"post":{"tags":["routines"],"operationId":"test_routine","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRoutineRequest"}}},"required":true},"responses":{"200":{"description":"What the spec would do with the source: every stage in order, the predicted outcome and the rendered prompt. Nothing is written and no run is started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRoutineResponse"}}}},"400":{"description":"The body is not a valid request, `spec` is missing, or the source does not fit the routine's trigger"},"401":{"description":"Unauthorized"},"404":{"description":"The event or repository was not found"},"413":{"description":"The body is larger than 6 MiB or the payload larger than 5 MiB"},"422":{"description":"The spec is invalid or the payload is not a routine event of a registered repository; `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"429":{"description":"More than 30 tests or dry runs in a minute, or Forkline is busy; retry after the number of seconds in the Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/validate":{"post":{"tags":["routines"],"operationId":"validate_routine","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRoutineRequest"}}},"required":true},"responses":{"200":{"description":"The spec is valid: the repositories it selects, warnings and the defaults it gets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateRoutineResponse"}}}},"400":{"description":"The body is not a valid request"},"401":{"description":"Unauthorized"},"413":{"description":"The body is larger than 256 KiB"},"422":{"description":"The spec or the name is invalid; `errors` lists every problem with a JSON pointer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"429":{"description":"More than 120 validations in a minute","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}":{"get":{"tags":["routines"],"operationId":"get_routine","responses":{"200":{"description":"Routine details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"}},"security":[{"bearer_auth":[]}]},"put":{"tags":["routines"],"operationId":"update_routine","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateRoutineRequest"}}},"required":true},"responses":{"200":{"description":"Routine updated. When the update turns the routine into an `on.webhook` routine the response carries the new signing secret, once.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"400":{"description":"Invalid request"},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"},"409":{"description":"The owner already has a routine with this name"},"422":{"description":"The spec is invalid; `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}}},"security":[{"bearer_auth":[]}]},"delete":{"tags":["routines"],"operationId":"delete_routine","responses":{"204":{"description":"Routine deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/backtest":{"post":{"tags":["routines"],"operationId":"backtest_saved_routine","parameters":[{"name":"id","in":"path","description":"Routine ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacktestRoutineRequest"}}},"required":true},"responses":{"200":{"description":"What the saved spec would have done with the owner's stored events of the last `days` days. Nothing is written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacktestRoutineResponse"}}}},"400":{"description":"The body is not a valid request, `spec` was sent, or `days`, `limit`, `show` or `pin_event_id` is invalid"},"401":{"description":"Unauthorized"},"404":{"description":"The routine, or the pinned event, was not found"},"413":{"description":"The body is larger than 256 KiB"},"422":{"description":"The saved spec no longer validates; `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"429":{"description":"More than 60 back-tests in a minute","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/disable":{"post":{"tags":["routines"],"operationId":"disable_routine","responses":{"200":{"description":"Routine disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/enable":{"post":{"tags":["routines"],"operationId":"enable_routine","parameters":[{"name":"id","in":"path","description":"Routine ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Routine enabled: `disabled` is now `published`","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"400":{"description":"The routine is not disabled, or an `on.webhook` routine has no signing secret"},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"},"409":{"description":"The owner has reached the published routine limit"},"422":{"description":"The stored spec no longer validates (for example the selection now matches more than 200 repositories); `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/publish":{"post":{"tags":["routines"],"operationId":"publish_routine","responses":{"200":{"description":"Routine published","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"400":{"description":"The routine is not a draft, or it is an `on.webhook` routine without a signing secret"},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"},"409":{"description":"The owner has reached the published routine limit"},"422":{"description":"The spec is no longer valid; `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/run":{"post":{"tags":["routines"],"operationId":"run_routine","parameters":[{"name":"id","in":"path","description":"Routine ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","description":"A real run repeated with the same key starts nothing the second time (the key is separate from the webhook's idempotency header)","required":false,"schema":{"type":["string","null"]}}],"requestBody":{"description":"What to run. The body is optional: an empty body runs the routine on all its selected repositories","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/RunRoutineRequest"},{"type":"null"}]}}}},"responses":{"200":{"description":"A dry run: the verdict, rendered prompt and cost estimate per repository, nothing written. A real run: the event, the outcome of every repository and the tasks created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunRoutineResponse"}}}},"400":{"description":"The body is not a valid request (an unknown field is refused, so a typo cannot start a run), or a field is not allowed for the routine's trigger (`payload` and `event_id` do not go together, nor `event_id` and `repositories`)"},"401":{"description":"Unauthorized"},"403":{"description":"The token lacks the `routines:execute` scope"},"404":{"description":"The routine is not yours, the feature is off, or the event was not found"},"409":{"description":"A real run of a draft: publish it first (`ROUTINE_DRAFT` in the message). A dry run of a draft works; published and disabled routines can be run"},"413":{"description":"The body is larger than 6 MiB or the payload larger than 5 MiB"},"422":{"description":"The run was refused; each issue has a code and a JSON pointer: `repository_not_selected`, `filters_not_matched` (real runs only), `event_fields_not_stored`, `event_repository_unavailable`, `fan_out_too_large`. A saved spec that no longer validates returns the usual spec issues","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"429":{"description":"More than 10 real runs (30 dry runs) in a minute, or Forkline is busy; retry after the number of seconds in the Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/runs":{"get":{"tags":["routines"],"operationId":"list_routine_runs","parameters":[{"name":"id","in":"path","description":"Routine ID","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"outcome","in":"query","description":"Comma list of outcomes (`task_created`, `superseded`, `filtered`, ...) and groups\n(`ran`, `skipped`, `limited`, `errors`). `skipped` includes `limited`. Default: all.","required":false,"schema":{"type":"string"}},{"name":"repository_id","in":"query","description":"Only runs for this repository id. Not together with `repository`.","required":false,"schema":{"type":"string"}},{"name":"repository","in":"query","description":"Only runs for this repository, `owner/name`, compared case-insensitively. Not\ntogether with `repository_id`.","required":false,"schema":{"type":"string"}},{"name":"number","in":"query","description":"A pull request or issue number.","required":false,"schema":{"type":"integer","format":"int64"}},{"name":"trigger_source","in":"query","description":"`event`, `schedule`, `webhook` or `manual`.","required":false,"schema":{"type":"string"}},{"name":"days","in":"query","description":"How many days back, 1 to 7. Default 7.","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"limit","in":"query","description":"Page size, 1 to 200. Default 50.","required":false,"schema":{"type":"integer","format":"int32","minimum":0}},{"name":"cursor","in":"query","description":"The `next_cursor` of the previous page.","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Runs of the routine, newest first. `counts` is present on the first page only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRoutineRunsResponse"}}}},"400":{"description":"A parameter or the cursor is invalid"},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/tasks":{"get":{"tags":["routines"],"operationId":"list_routine_tasks","responses":{"200":{"description":"List of tasks triggered by this routine","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRoutineTasksResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/tasks/{task_id}":{"get":{"tags":["routines"],"operationId":"get_routine_task","responses":{"200":{"description":"Task detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskDetailResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Routine or task not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/test":{"post":{"tags":["routines"],"operationId":"test_saved_routine","parameters":[{"name":"id","in":"path","description":"Routine ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRoutineRequest"}}},"required":true},"responses":{"200":{"description":"What the saved spec would do with the source: every stage in order, the predicted outcome and the rendered prompt. Nothing is written and no run is started.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestRoutineResponse"}}}},"400":{"description":"The body is not a valid request, `spec` was sent, or the source does not fit the routine's trigger"},"401":{"description":"Unauthorized"},"404":{"description":"The routine, event or repository was not found"},"413":{"description":"The body is larger than 6 MiB or the payload larger than 5 MiB"},"422":{"description":"The saved spec no longer validates, or the payload is not a routine event of a registered repository; `errors` has a JSON pointer per problem","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}}},"429":{"description":"More than 30 tests or dry runs in a minute, or Forkline is busy; retry after the number of seconds in the Retry-After header","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RateLimitResponse"}}}}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/webhook/rotate-secret":{"post":{"tags":["routines"],"operationId":"rotate_webhook_secret","responses":{"200":{"description":"A new signing secret, shown once; the previous one stops working","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"400":{"description":"The routine is not an `on.webhook` routine"},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"}},"security":[{"bearer_auth":[]}]}},"/v1/routines/{id}/webhook/secret":{"put":{"tags":["routines"],"operationId":"set_webhook_secret","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetWebhookSecretRequest"}}},"required":true},"responses":{"200":{"description":"The secret is stored, encrypted. It is never returned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoutineResponse"}}}},"400":{"description":"The routine does not take a pasted secret (a token or `forkline` signature routine has a generated one), or the secret is not 16 to 512 bytes"},"401":{"description":"Unauthorized"},"404":{"description":"Routine not found"}},"security":[{"bearer_auth":[]}]}},"/v1/runner-sizes":{"get":{"tags":["runners"],"operationId":"list_runner_sizes","responses":{"200":{"description":"List of available runner sizes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunnerSizesResponse"}}}}}}},"/v1/runners":{"get":{"tags":["runners"],"operationId":"list_all_runners","parameters":[{"name":"repository_id","in":"path","required":true,"schema":{"type":["string","null"],"format":"uuid"}},{"name":"status","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"connector_id","in":"path","required":true,"schema":{"type":["string","null"],"format":"uuid"}},{"name":"source","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"page","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"per_page","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"sort_by","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"sort_order","in":"path","required":true,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"List of all runners for the user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunnersResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/runners/bulk-action":{"post":{"tags":["runners"],"operationId":"bulk_runner_action","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkRunnerActionRequest"}}},"required":true},"responses":{"200":{"description":"Bulk action result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkRunnerActionResponse"}}}},"400":{"description":"Bad request"},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/runners/ids":{"get":{"tags":["runners"],"operationId":"list_runner_ids","parameters":[{"name":"repository_id","in":"path","required":true,"schema":{"type":["string","null"],"format":"uuid"}},{"name":"status","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"connector_id","in":"path","required":true,"schema":{"type":["string","null"],"format":"uuid"}},{"name":"source","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"page","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"per_page","in":"path","required":true,"schema":{"type":["integer","null"],"format":"int64"}},{"name":"sort_by","in":"path","required":true,"schema":{"type":["string","null"]}},{"name":"sort_order","in":"path","required":true,"schema":{"type":["string","null"]}}],"responses":{"200":{"description":"List of all runner IDs for the user","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunnerIdsResponse"}}}},"401":{"description":"Unauthorized"}},"security":[{"bearer_auth":[]}]}},"/v1/runners/{runner_id}":{"get":{"tags":["runners"],"operationId":"get_runner","parameters":[{"name":"runner_id","in":"path","description":"Runner ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Runner details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Runner"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Runner not found"}},"security":[{"bearer_auth":[]}]},"delete":{"tags":["runners"],"operationId":"stop_runner","parameters":[{"name":"runner_id","in":"path","description":"Runner ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"Runner stopped/deleted"},"401":{"description":"Unauthorized"},"404":{"description":"Runner not found"}},"security":[{"bearer_auth":[]}]}},"/v1/runners/{runner_id}/events":{"get":{"tags":["runners"],"operationId":"list_runner_events","parameters":[{"name":"runner_id","in":"path","description":"Runner ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"List of runner events","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunnerEventsResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Runner not found"}},"security":[{"bearer_auth":[]}]}},"/v1/runners/{runner_id}/restart":{"post":{"tags":["runners"],"operationId":"restart_runner","parameters":[{"name":"runner_id","in":"path","description":"Runner ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Runner restarted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Runner"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Runner not found"},"409":{"description":"Runner is not in a restartable state"}},"security":[{"bearer_auth":[]}]}},"/v1/runners/{runner_id}/settings":{"get":{"tags":["runners"],"operationId":"get_runner_settings","parameters":[{"name":"runner_id","in":"path","description":"Runner ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Runner settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunnerSettingsResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Runner not found"}},"security":[{"bearer_auth":[]}]},"put":{"tags":["runners"],"operationId":"update_runner_settings","parameters":[{"name":"runner_id","in":"path","description":"Runner ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSettingsRequest"}}},"required":true},"responses":{"200":{"description":"Runner settings updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunnerSettingsResponse"}}}},"401":{"description":"Unauthorized"},"404":{"description":"Runner not found"}},"security":[{"bearer_auth":[]}]}},"/v1/runners/{runner_ref}/attach-grant":{"post":{"tags":["runners"],"operationId":"attach_runner","parameters":[{"name":"runner_ref","in":"path","description":"Runner UUID, short reference, or unambiguous name","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Attach grant issued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachGrantResponse"}}}},"400":{"description":"Redis unavailable"},"401":{"description":"Unauthorized"},"404":{"description":"Runner not found"},"409":{"description":"Runner not running or changed state concurrently"}},"security":[{"bearer_auth":[]}]}}},"components":{"schemas":{"AccountSecret":{"type":"object","description":"Account-level secret metadata: the value lives in Vault at\n`secret/data/calypso/users/{user_id}/account-secrets/{name}` and is never stored in\nthe database or returned by the API (ADR-0045, kept by ADR-0057 §8).","required":["id","user_id","name","created_at","updated_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"description":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"rotated_at":{"type":["string","null"],"format":"date-time","description":"When the Vault value behind this row was last rewritten."},"updated_at":{"type":"string","format":"date-time"},"user_id":{"type":"string","format":"uuid"}}},"AccountSecretListItem":{"allOf":[{"$ref":"#/components/schemas/AccountSecret"},{"type":"object","properties":{"used_by":{"type":"array","items":{"$ref":"#/components/schemas/SecretUsedBy"},"description":"The user's MCP servers whose credential bindings reference `account/<name>`."}}}],"description":"An account secret as listed: metadata plus the MCP servers that bind it."},"AnalyticsHistoryResponse":{"type":"object","required":["points"],"properties":{"points":{"type":"array","items":{"$ref":"#/components/schemas/HistoryPointResponse"}}}},"AnalyticsOverviewResponse":{"type":"object","required":["input_tokens","output_tokens","reasoning_tokens","cache_read_tokens","cache_write_tokens","total_tokens","runner_hours","sessions_count","active_provider_count","active_model_count","active_repository_count"],"properties":{"active_model_count":{"type":"integer","format":"int64"},"active_provider_count":{"type":"integer","format":"int64"},"active_repository_count":{"type":"integer","format":"int64"},"cache_read_tokens":{"type":"integer","format":"int64"},"cache_write_tokens":{"type":"integer","format":"int64"},"input_tokens":{"type":"integer","format":"int64"},"output_tokens":{"type":"integer","format":"int64"},"reasoning_tokens":{"type":"integer","format":"int64"},"runner_hours":{"type":"number","format":"double"},"sessions_count":{"type":"integer","format":"int64"},"total_tokens":{"type":"integer","format":"int64"}}},"ApiTokenCreateResponse":{"type":"object","required":["token","api_token"],"properties":{"api_token":{"$ref":"#/components/schemas/ApiTokenResponse"},"token":{"type":"string"}}},"ApiTokenListResponse":{"type":"object","required":["api_tokens"],"properties":{"api_tokens":{"type":"array","items":{"$ref":"#/components/schemas/ApiTokenResponse"}}}},"ApiTokenResponse":{"type":"object","required":["id","name","token_prefix","scopes","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"id":{"type":"string","format":"uuid"},"last_used_at":{"type":["string","null"],"format":"date-time"},"name":{"type":"string"},"revoked_at":{"type":["string","null"],"format":"date-time"},"scopes":{"type":"array","items":{"type":"string"}},"token_prefix":{"type":"string"}}},"AttachGrantResponse":{"type":"object","required":["url","attach_grant"],"properties":{"attach_grant":{"type":"string"},"url":{"type":"string"}}},"AutoPrReviewAction":{"type":"string","enum":["comment","commit"]},"AutoPrReviewScope":{"type":"string","enum":["all","forkline_only"]},"BacktestCounts":{"type":"object","required":["matched","would_run","would_run_unverified","filtered","errors"],"properties":{"errors":{"type":"integer","format":"int64"},"filtered":{"type":"integer","format":"int64"},"matched":{"type":"integer","format":"int64"},"would_run":{"type":"integer","format":"int64"},"would_run_unverified":{"type":"integer","format":"int64"}}},"BacktestRoutineRequest":{"type":"object","properties":{"days":{"type":["integer","null"],"format":"int32","description":"Days of stored events to replay, 1 to 7 (default 7).","minimum":0},"limit":{"type":["integer","null"],"format":"int32","description":"Rows returned, 1 to 500 (default 100).","minimum":0},"name":{"type":["string","null"]},"pin_event_id":{"type":["string","null"],"format":"uuid","description":"An event listed first whatever its time (the event the routine was started from)."},"show":{"type":["string","null"],"description":"Which rows to return: `all`, `would_run` or `skipped`."},"spec":{}}},"BacktestRoutineResponse":{"type":"object","required":["window","repositories","counts","filtered_by_stage","group_conflicts","estimate","events","not_evaluated"],"properties":{"counts":{"$ref":"#/components/schemas/BacktestCounts"},"estimate":{"$ref":"#/components/schemas/CostEstimate"},"events":{"type":"array","items":{"$ref":"#/components/schemas/BacktestRow"}},"filtered_by_stage":{"type":"object","description":"How many events each stage filtered, in stage order.","additionalProperties":{"type":"integer","format":"int64"},"propertyNames":{"type":"string","description":"The named steps of handling one event for one routine, in the order they run.","enum":["overload","fan_out","event","repository","self_guard","bots","draft","fork","branches","labels","authors","command","paths","when","trigger_policy","template","event_key","concurrency","run_limit","credits","submit"]}},"group_conflicts":{"$ref":"#/components/schemas/GroupConflicts"},"not_evaluated":{"type":"array","items":{"$ref":"#/components/schemas/RuntimeCheck"}},"repositories":{"$ref":"#/components/schemas/ResolvedRepositories"},"schedule":{"oneOf":[{"$ref":"#/components/schemas/ScheduleEstimate"},{"type":"null"}]},"webhook":{"oneOf":[{"$ref":"#/components/schemas/WebhookEstimate"},{"type":"null"}]},"window":{"$ref":"#/components/schemas/BacktestWindow"}}},"BacktestRow":{"type":"object","required":["event","repository","outcome","reason","unverified_fields","pinned"],"properties":{"event":{"$ref":"#/components/schemas/EventHeadline"},"outcome":{"$ref":"#/components/schemas/PredictedOutcome"},"pinned":{"type":"boolean"},"reason":{"type":"string"},"repository":{"$ref":"#/components/schemas/RepositoryRef"},"stage":{"oneOf":[{"$ref":"#/components/schemas/Stage"},{"type":"null"}]},"unverified_fields":{"type":"array","items":{"type":"string"}}}},"BacktestWindow":{"type":"object","required":["from","to","days","covered_days","events_scanned","truncated"],"properties":{"covered_days":{"type":"number","format":"double"},"days":{"type":"integer","format":"int32","minimum":0},"events_scanned":{"type":"integer","format":"int64"},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"truncated":{"type":"boolean"}}},"BulkAction":{"type":"string","enum":["stop","delete"]},"BulkRunnerActionRequest":{"type":"object","required":["action","runner_ids"],"properties":{"action":{"$ref":"#/components/schemas/BulkAction"},"runner_ids":{"type":"array","items":{"type":"string","format":"uuid"}}}},"BulkRunnerActionResponse":{"type":"object","required":["succeeded","failed","errors"],"properties":{"errors":{"type":"array","items":{"type":"string"}},"failed":{"type":"integer","minimum":0},"succeeded":{"type":"integer","minimum":0}}},"ConcurrencyGroup":{"type":"string","enum":["pr","issue","repository","routine"]},"ConnectorInfo":{"type":"object","required":["id","name","provider","has_webhook_secret","insecure_tls","created_at"],"properties":{"account_name":{"type":["string","null"]},"automation_actor_username":{"type":["string","null"]},"base_url":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"deleted_at":{"type":["string","null"],"format":"date-time"},"git_username":{"type":["string","null"]},"has_webhook_secret":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"insecure_tls":{"type":"boolean"},"installation_id":{"type":["integer","null"],"format":"int64"},"name":{"type":"string"},"provider":{"$ref":"#/components/schemas/ConnectorProvider"}}},"ConnectorProvider":{"type":"string","enum":["github","gitlab","forgejo"]},"CostEstimate":{"type":"object","required":["runner_sessions_per_week","credits_per_run_max","credits_per_week_max","runner_size","timeout_minutes"],"properties":{"credits_per_run_max":{"type":"integer","format":"int64"},"credits_per_week_max":{"type":"integer","format":"int64"},"runner_sessions_per_week":{"type":"number","format":"double"},"runner_size":{"type":"string"},"timeout_minutes":{"type":"integer","format":"int32","minimum":0}}},"CreateApiTokenRequest":{"type":"object","required":["name","scopes"],"properties":{"expires_in_days":{"type":["integer","null"],"format":"int64"},"name":{"type":"string"},"never_expires":{"type":"boolean","default":false},"scopes":{"type":"array","items":{"type":"string"}}}},"CreateMcpServerRequest":{"type":"object","required":["name","source","repositories"],"properties":{"credential_bindings":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"enabled":{"type":"boolean","description":"Defaults to false."},"inputs":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"name":{"type":"string"},"repositories":{"$ref":"#/components/schemas/RepositorySelector"},"slug":{"type":["string","null"]},"source":{"$ref":"#/components/schemas/NewMcpServerSource"}}},"CreateRepositoryRequest":{"type":"object","description":"Request to add a new repository.","required":["connector_id","owner","name","repository_url"],"properties":{"allowed_users":{"type":["array","null"],"items":{"type":"string"}},"connector_id":{"type":"string","format":"uuid"},"default_model":{"type":["string","null"]},"default_runner_size":{"oneOf":[{"$ref":"#/components/schemas/RunnerSize"},{"type":"null"}]},"name":{"type":"string"},"owner":{"type":"string"},"repository_url":{"type":"string"},"trigger_policy":{"oneOf":[{"$ref":"#/components/schemas/TriggerPolicy"},{"type":"null"}]}}},"CreateRoutineRequest":{"type":"object","required":["name","spec"],"properties":{"description":{"type":["string","null"]},"name":{"type":"string"},"spec":{}}},"CreateSecretRequest":{"type":"object","required":["name","value"],"properties":{"name":{"type":"string"},"value":{"type":"string"}}},"CreditsResponse":{"type":"object","required":["balance","purchased_credits"],"properties":{"balance":{"type":"integer","format":"int64"},"purchased_credits":{"type":"integer","format":"int64"},"subscription":{"oneOf":[{"$ref":"#/components/schemas/SubscriptionCreditsInfo"},{"type":"null"}]}}},"CurrentUserResponse":{"type":"object","required":["id","external_id","email","groups","default_runner_size","auto_fix_ci","auto_fix_max_attempts","auto_fix_merge_conflicts","auto_fix_merge_conflicts_max_attempts","auto_pr_review","auto_pr_review_scope","auto_pr_review_action","experimental"],"properties":{"auto_fix_ci":{"type":"boolean"},"auto_fix_max_attempts":{"type":"integer","format":"int32"},"auto_fix_merge_conflicts":{"type":"boolean"},"auto_fix_merge_conflicts_max_attempts":{"type":"integer","format":"int32"},"auto_pr_review":{"type":"boolean"},"auto_pr_review_action":{"$ref":"#/components/schemas/AutoPrReviewAction"},"auto_pr_review_prompt":{"type":["string","null"]},"auto_pr_review_scope":{"$ref":"#/components/schemas/AutoPrReviewScope"},"default_model":{"type":["string","null"]},"default_runner_size":{"$ref":"#/components/schemas/RunnerSize"},"email":{"type":"string"},"experimental":{"type":"boolean"},"external_id":{"type":"string"},"groups":{"type":"array","items":{"type":"string"}},"id":{"type":"string","format":"uuid"},"max_active_runners":{"type":["integer","null"],"format":"int32"},"username":{"type":["string","null"]}}},"CustomModelConfig":{"type":"object","description":"Custom model configuration matching OpenCode's provider config format.","properties":{"contextWindow":{"type":["integer","null"],"format":"int64","description":"Context window size in tokens"},"modalities":{"oneOf":[{"$ref":"#/components/schemas/CustomModelModalities","description":"Input/output modalities supported"},{"type":"null"}]},"name":{"type":["string","null"],"description":"Display name for the model"},"options":{"oneOf":[{"$ref":"#/components/schemas/Value","description":"Provider-specific options"},{"type":"null"}]}}},"CustomModelModalities":{"type":"object","description":"Modalities for a custom model.","properties":{"input":{"type":["array","null"],"items":{"type":"string"},"description":"Input modalities (e.g., [\"text\", \"image\"])"},"output":{"type":["array","null"],"items":{"type":"string"},"description":"Output modalities (e.g., [\"text\"])"}}},"CustomProvider":{"type":"object","description":"A custom provider stored in the database.","required":["id","name","baseURL","models","created_at","updated_at"],"properties":{"baseURL":{"type":"string","description":"Base URL for API requests"},"created_at":{"type":"string","format":"date-time","description":"When the provider was created"},"id":{"type":"string","description":"Provider ID (user-defined)"},"models":{"type":"array","items":{"$ref":"#/components/schemas/CustomProviderModel"},"description":"Models available from this provider"},"name":{"type":"string","description":"Display name"},"npm":{"type":["string","null"],"description":"NPM package for SDK"},"updated_at":{"type":"string","format":"date-time","description":"When the provider was last updated"}}},"CustomProviderConfig":{"type":"object","description":"Custom provider configuration matching OpenCode's opencode.json format.","required":["name","models"],"properties":{"models":{"type":"object","description":"Models available from this provider","additionalProperties":{"$ref":"#/components/schemas/CustomModelConfig"},"propertyNames":{"type":"string"}},"name":{"type":"string","description":"Display name for the provider"},"npm":{"type":["string","null"],"description":"NPM package for the provider SDK"},"options":{"oneOf":[{"$ref":"#/components/schemas/CustomProviderOptions","description":"Provider options including baseURL"},{"type":"null"}]}}},"CustomProviderModalities":{"type":"object","properties":{"input":{"type":["array","null"],"items":{"type":"string"}},"output":{"type":["array","null"],"items":{"type":"string"}}}},"CustomProviderModel":{"type":"object","description":"A model within a custom provider.","required":["id","name","input_modalities","output_modalities"],"properties":{"context_window":{"type":["integer","null"],"format":"int64","description":"Context window size in tokens"},"id":{"type":"string","description":"Model ID (within the provider)"},"input_modalities":{"type":"array","items":{"type":"string"},"description":"Input modalities supported"},"name":{"type":"string","description":"Display name"},"output_modalities":{"type":"array","items":{"type":"string"},"description":"Output modalities supported"}}},"CustomProviderModelConfig":{"type":"object","properties":{"contextWindow":{"type":["integer","null"],"format":"int64"},"modalities":{"oneOf":[{"$ref":"#/components/schemas/CustomProviderModalities"},{"type":"null"}]},"name":{"type":["string","null"]}}},"CustomProviderOptions":{"type":"object","description":"Options for a custom provider.","properties":{"baseURL":{"type":["string","null"],"description":"Base URL for the provider API"}},"additionalProperties":{"$ref":"#/components/schemas/Value","description":"Additional provider-specific options"}},"DraftFromEventRequest":{"type":"object","required":["event_id"],"properties":{"event_id":{"type":"string","format":"uuid"},"facts":{"type":["array","null"],"items":{"type":"string"}},"widen":{"type":"boolean"}}},"DraftFromEventResponse":{"type":"object","required":["name","spec","provenance","facts","widen","event"],"properties":{"description":{"type":["string","null"]},"event":{"$ref":"#/components/schemas/EventHeadline"},"facts":{"type":"array","items":{"$ref":"#/components/schemas/EventFact"}},"name":{"type":"string"},"provenance":{"type":"array","items":{"$ref":"#/components/schemas/ProvenanceEntry"}},"spec":{},"widen":{"type":"array","items":{"$ref":"#/components/schemas/WidenSuggestion"}}}},"EffectiveAgent":{"type":"object","required":["runner_size","timeout_minutes"],"properties":{"runner_size":{"type":"string"},"timeout_minutes":{"type":"integer","format":"int32","minimum":0}}},"EffectiveConcurrency":{"type":"object","required":["group","on_conflict","max_active"],"properties":{"group":{"$ref":"#/components/schemas/ConcurrencyGroup"},"max_active":{"type":"integer","format":"int32","minimum":0},"on_conflict":{"$ref":"#/components/schemas/OnConflict"}}},"EffectiveDefaults":{"type":"object","required":["concurrency","limits","agent"],"properties":{"agent":{"$ref":"#/components/schemas/EffectiveAgent"},"concurrency":{"$ref":"#/components/schemas/EffectiveConcurrency"},"limits":{"$ref":"#/components/schemas/EffectiveLimits"}}},"EffectiveLimits":{"type":"object","required":["max_runs_per_pr"],"properties":{"max_runs_per_pr":{"type":"integer","format":"int32","minimum":0}}},"ErrorResponse":{"type":"object","required":["error"],"properties":{"code":{"type":["string","null"]},"error":{"type":"string"}}},"EventActor":{"type":"object","required":["login","is_bot","is_self"],"properties":{"is_bot":{"type":"boolean"},"is_self":{"type":"boolean"},"login":{"type":"string"}}},"EventFact":{"type":"object","required":["key","label","value","default_checked","filter"],"properties":{"checked":{"type":["boolean","null"]},"default_checked":{"type":"boolean"},"filter":{"description":"The `filters` fragment this fact adds to a drafted spec."},"key":{"type":"string"},"label":{"type":"string"},"value":{"type":"string"}}},"EventHeadline":{"type":"object","required":["source","received_at","title"],"properties":{"actor":{"oneOf":[{"$ref":"#/components/schemas/EventActor"},{"type":"null"}]},"delivery_id":{"type":["string","null"]},"forge":{"type":["string","null"]},"id":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]},"number":{"type":["integer","null"],"format":"int64"},"received_at":{"type":"string","format":"date-time"},"repository":{"oneOf":[{"$ref":"#/components/schemas/RepositoryRef"},{"type":"null"}]},"source":{"$ref":"#/components/schemas/TriggerSource"},"title":{"type":"string"},"url":{"type":["string","null"]}}},"EventReaction":{"type":"object","required":["routine_id","routine_name","run_id","outcome","reason"],"properties":{"outcome":{"$ref":"#/components/schemas/RunOutcome"},"reason":{"type":"string"},"routine_id":{"type":"string","format":"uuid"},"routine_name":{"type":"string"},"run_id":{"type":"string","format":"uuid"}}},"GetMcpCatalogEntryResponse":{"type":"object","description":"Response of the catalog detail endpoint.","required":["entry"],"properties":{"entry":{"$ref":"#/components/schemas/McpCatalogEntry"},"revisions":{"type":"array","items":{"$ref":"#/components/schemas/McpCatalogRevision"}}}},"GroupConflicts":{"type":"object","required":["group","on_conflict","count"],"properties":{"count":{"type":"integer","format":"int64"},"group":{"$ref":"#/components/schemas/ConcurrencyGroup"},"on_conflict":{"$ref":"#/components/schemas/OnConflict"}}},"HistoryPointResponse":{"type":"object","required":["day","input_tokens","output_tokens","reasoning_tokens","cache_read_tokens","cache_write_tokens","total_tokens","runner_hours","sessions_count"],"properties":{"cache_read_tokens":{"type":"integer","format":"int64"},"cache_write_tokens":{"type":"integer","format":"int64"},"day":{"type":"string","format":"date"},"input_tokens":{"type":"integer","format":"int64"},"output_tokens":{"type":"integer","format":"int64"},"reasoning_tokens":{"type":"integer","format":"int64"},"runner_hours":{"type":"number","format":"double"},"sessions_count":{"type":"integer","format":"int64"},"total_tokens":{"type":"integer","format":"int64"}}},"ImportCustomProviderRequest":{"type":"object","description":"Request to import a custom provider.","required":["provider"],"properties":{"provider":{"type":"object","description":"Provider configurations, keyed by provider ID","additionalProperties":{"$ref":"#/components/schemas/CustomProviderConfig"},"propertyNames":{"type":"string"}}}},"InsufficientCreditsResponse":{"type":"object","required":["error","code","message","current_balance","required_minimum","subscription_credits","purchased_credits"],"properties":{"code":{"type":"string"},"current_balance":{"type":"integer","format":"int64"},"error":{"type":"string"},"message":{"type":"string"},"purchased_credits":{"type":"integer","format":"int64"},"required_minimum":{"type":"integer","format":"int64"},"subscription_credits":{"type":"integer","format":"int64"}}},"LastRun":{"type":"object","required":["created_at","outcome","reason"],"properties":{"created_at":{"type":"string","format":"date-time"},"outcome":{"$ref":"#/components/schemas/RunOutcome"},"reason":{"type":"string"}}},"ListAccountSecretsResponse":{"type":"object","required":["secrets"],"properties":{"secrets":{"type":"array","items":{"$ref":"#/components/schemas/AccountSecretListItem"}}}},"ListConnectorsResponse":{"type":"object","required":["connectors"],"properties":{"connectors":{"type":"array","items":{"$ref":"#/components/schemas/ConnectorInfo"}}}},"ListCustomProvidersResponse":{"type":"object","description":"Response for listing custom providers.","required":["providers"],"properties":{"providers":{"type":"array","items":{"$ref":"#/components/schemas/CustomProvider"},"description":"List of custom providers"}}},"ListMcpCatalogResponse":{"type":"object","description":"Response of the catalog list endpoint.","required":["entries"],"properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/McpCatalogEntry"}},"next_cursor":{"type":["string","null"],"description":"Keyset cursor for the next page: the `external_id` of the last entry returned.\n`None` when this page is the last one."},"snapshot_stale_at":{"type":["string","null"],"format":"date-time","description":"Set while a stale last-known-good snapshot is being served (plan P2.2)."}}},"ListMcpServersResponse":{"type":"object","required":["servers"],"properties":{"servers":{"type":"array","items":{"$ref":"#/components/schemas/McpServerListItem"}}}},"ListModelsResponse":{"type":"object","required":["providers"],"properties":{"providers":{"type":"array","items":{"$ref":"#/components/schemas/Provider"}}}},"ListProvidersResponse":{"type":"object","required":["providers"],"properties":{"providers":{"type":"array","items":{"$ref":"#/components/schemas/ProviderInfo"}}}},"ListRecentEventsResponse":{"type":"object","required":["events","older_dropped"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/RecentEvent"}},"next_cursor":{"type":["string","null"]},"older_dropped":{"type":"boolean"}}},"ListRepositoriesResponse":{"type":"object","required":["repositories","total","offset","limit","has_more"],"properties":{"has_more":{"type":"boolean"},"limit":{"type":"integer","format":"int64"},"offset":{"type":"integer","format":"int64"},"repositories":{"type":"array","items":{"$ref":"#/components/schemas/Repository"}},"total":{"type":"integer","format":"int64"}}},"ListRoutineRunsResponse":{"type":"object","required":["runs"],"properties":{"counts":{"oneOf":[{"$ref":"#/components/schemas/RunCounts"},{"type":"null"}]},"next_cursor":{"type":["string","null"]},"runs":{"type":"array","items":{"$ref":"#/components/schemas/RoutineRun"}}}},"ListRoutineTasksResponse":{"type":"object","required":["tasks"],"properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/TaskSummary"}}}},"ListRoutinesResponse":{"type":"object","required":["routines"],"properties":{"routines":{"type":"array","items":{"$ref":"#/components/schemas/RoutineResponse"}}}},"ListRunnerEventsResponse":{"type":"object","required":["events"],"properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/RunnerEventResponse"}}}},"ListRunnerIdsResponse":{"type":"object","required":["runner_ids"],"properties":{"runner_ids":{"type":"array","items":{"type":"string","format":"uuid"}}}},"ListRunnerSizesResponse":{"type":"object","required":["sizes"],"properties":{"sizes":{"type":"array","items":{"$ref":"#/components/schemas/RunnerSizeSpec"}}}},"ListRunnersResponse":{"type":"object","required":["runners","total","has_more"],"properties":{"has_more":{"type":"boolean"},"runners":{"type":"array","items":{"$ref":"#/components/schemas/Runner"}},"total":{"type":"integer","format":"int64"}}},"ListSecretsResponse":{"type":"object","required":["secrets"],"properties":{"secrets":{"type":"array","items":{"$ref":"#/components/schemas/RepositorySecret"}}}},"LocalMcpConfig":{"type":"object","description":"Locally-run MCP server config. `environment` values are `{env:NAME}` references or\nliteral non-secret inputs.","required":["command"],"properties":{"args":{"type":"array","items":{"type":"string"}},"command":{"type":"string"},"environment":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"timeout_ms":{"type":"integer","format":"int32","minimum":0}}},"McpCatalogEntry":{"type":"object","description":"A catalog entry as served by the API and the CLI.\n\n`tier`, the gate fields, `plan_hash` and `credential_requirements` mirror the\ndefault revision, so browse filters and the TIER column read them directly.","required":["id","external_id","source","canonical_name","slug","title","transport","tier","status","curated","hidden","created_at","updated_at"],"properties":{"canonical_name":{"type":"string","description":"Upstream canonical (reverse-DNS) name."},"category":{"type":["string","null"]},"compiler_version":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"credential_requirements":{"type":"array","items":{"$ref":"#/components/schemas/McpCatalogSecretRequirement"}},"curated":{"type":"boolean","description":"Overlay/built-in entries stay browsable even at `compatible` (ADR-0057 §5)."},"default_revision":{"oneOf":[{"$ref":"#/components/schemas/McpCatalogRevision","description":"Loaded on the detail path only; `None` in list responses."},{"type":"null"}]},"default_revision_id":{"type":["string","null"],"format":"uuid"},"description":{"type":["string","null"]},"external_id":{"type":"string","description":"Source-qualified identity the API and CLI address entries by\n(`mcp-registry/<reverse-dns-name>`, plan P2.4)."},"hidden":{"type":"boolean","description":"Deny-listed by the overlay (spam, bulk importers): visible only on opt-in\ndiscovery."},"id":{"type":"string","format":"uuid"},"installable":{"type":"boolean","description":"A new server can be installed from this entry (false for unsupported entries)."},"latest_version":{"type":["string","null"],"description":"The latest version. On the detail response it is the newest *installable* version\n(what an install defaults to); in lists it is the newest upstream version."},"license":{"type":["string","null"]},"plan_hash":{"type":["string","null"]},"publisher":{"type":["string","null"],"description":"Who publishes the server, from its registry namespace."},"quarantine_reason":{"type":["string","null"],"description":"Why an operator quarantined this entry (`status == quarantined`), `None` otherwise.\nSurfaced so an entry that disappears from the installable set is explainable\n(plan P6.5) instead of silently hidden."},"recipe_version":{"type":["string","null"]},"remediation":{"type":["string","null"]},"repository_url":{"type":["string","null"]},"requirements":{"type":"array","items":{"$ref":"#/components/schemas/McpCatalogRequirement"},"description":"What the user must provide, humanised and in declaration order."},"runs":{"$ref":"#/components/schemas/McpCatalogRuns","description":"`local` runs in the user's runner, `hosted` is a remote URL."},"slug":{"type":"string","description":"Short alias a user types (`context7`)."},"source":{"$ref":"#/components/schemas/McpCatalogSource"},"status":{"$ref":"#/components/schemas/McpCatalogEntryStatus"},"tags":{"type":"array","items":{"type":"string"}},"tier":{"$ref":"#/components/schemas/McpCatalogTierView","description":"`verified|unverified|unsupported`. An entry is Verified when any of its revisions is."},"title":{"type":"string"},"transport":{"$ref":"#/components/schemas/McpTransport"},"unavailable_reason":{"type":["string","null"],"description":"Humanised reason an unsupported entry cannot be used, for search results."},"unsupported_detail":{"type":["string","null"]},"unsupported_reason":{"oneOf":[{"$ref":"#/components/schemas/McpCatalogGateCode"},{"type":"null"}]},"updated_at":{"type":"string","format":"date-time"},"verified_versions":{"type":"array","items":{"type":"string"},"description":"Versions whose revision is Verified, newest first (\"Verified on 1.2.0\")."},"version":{"type":["string","null"],"description":"Version of the default revision."},"warnings":{"type":"array","items":{"type":"string"}},"website_url":{"type":["string","null"]}}},"McpCatalogEntryStatus":{"type":"string","description":"Catalog lifecycle status. `Quarantined` blocks *new* installs only — existing\nconnections are never disrupted or deleted (plan P6.5).","enum":["active","quarantined","retired"]},"McpCatalogEvidence":{"type":"object","description":"Tier evidence stored in the database (plan P1.5 and the Q3 resolution: DB-backed,\nnot git-backed), written by the P6 verification harness for a\n`(revision, plan_hash)` pair.","properties":{"evidence_ref":{"type":["string","null"],"description":"Reference to the stored artifact for this evidence."},"failure_reason":{"type":["string","null"],"description":"Populated when a probe failed, so the UI can show *why* (plan P6.2)."},"opencode_version":{"type":["string","null"]},"opencode_version_target":{"type":["string","null"],"description":"OpenCode version the harness was asked to target. Only populated when\n`verification_method` is not `opencode-integrated` (since direct-child runs\ndon't exercise OpenCode, the observed `opencode_version` stays NULL and this\nfield records what was requested). Additive field."},"plan_hash":{"type":["string","null"]},"probes":{"type":"array","items":{"$ref":"#/components/schemas/McpVerificationProbe"}},"run_ref":{"type":["string","null"],"description":"Reference to the harness run that produced this evidence (logs + transcript)."},"runner_image":{"type":["string","null"]},"scenario_id":{"type":["string","null"]},"tested_at":{"type":["string","null"],"format":"date-time"},"tested_version":{"type":["string","null"]},"tool_call_probe":{"oneOf":[{"$ref":"#/components/schemas/McpToolCallProbe"},{"type":"null"}]},"verification_method":{"type":["string","null"],"description":"How the harness verified this entry: `direct-child` (spawned the server),\n`remote-direct` (called a hosted server), or `opencode-integrated` (exercised\nOpenCode's MCP client stack). Additive field — absent on older evidence rows."},"warnings":{"type":"array","items":{"type":"string"}}}},"McpCatalogGateCode":{"type":"string","description":"Gate reason code for `unsupported` entries (ADR-0057 §2/§4, plan P2.7).","enum":["oci","cargo","nuget","mcpb","oauth-remote","egress","no-plan","invalid-plan"]},"McpCatalogRequirement":{"type":"object","description":"One thing a user must provide to use a catalog server, humanised.","required":["name","label","secret","required"],"properties":{"default":{"type":["string","null"],"description":"Suggested value for a non-secret input."},"description":{"type":["string","null"]},"label":{"type":"string","description":"Display label, for example \"Grafana API key\"."},"name":{"type":"string","description":"The slot's name, which a server's inputs or credential bindings are keyed by."},"required":{"type":"boolean"},"secret":{"type":"boolean","description":"A secret value: stored as a secret, never shown again."}}},"McpCatalogRevision":{"type":"object","description":"One upstream version of a catalog entry, with its own frozen plan and tier.","required":["id","entry_id","version","transport","tier","upstream_status","created_at","updated_at"],"properties":{"compiled_at":{"type":["string","null"],"format":"date-time"},"compiler_version":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"credential_requirements":{"type":"array","items":{"$ref":"#/components/schemas/McpCatalogSecretRequirement"}},"entry_id":{"type":"string","format":"uuid"},"evidence":{"oneOf":[{"$ref":"#/components/schemas/McpCatalogEvidence"},{"type":"null"}]},"id":{"type":"string","format":"uuid"},"installable":{"type":"boolean","description":"Whether a new server can be installed from this revision."},"latest":{"type":"boolean","description":"This is the newest installable version of the entry; installs default to it."},"launch_argv":{"type":["array","null"],"items":{"type":"string"},"description":"The command line a local server runs, or `None` for a hosted one: shown to users as\n\"Runs as\". Derived from the plan; a hosted server shows its URL in the plan."},"plan":{"oneOf":[{"$ref":"#/components/schemas/McpInstallPlan"},{"type":"null"}]},"plan_hash":{"type":["string","null"]},"recipe_version":{"type":["string","null"]},"remediation":{"type":["string","null"]},"requirements":{"type":"array","items":{"$ref":"#/components/schemas/McpCatalogRequirement"},"description":"Everything a server installed from THIS revision asks the user for, in order: the\ncredentials (secret or not), then the fillable plan arguments. Derived by\n[`plan_requirements`]; the add flow and the server page read the same list."},"superseded_at":{"type":["string","null"],"format":"date-time"},"superseded_by":{"type":["string","null"],"description":"Version that superseded this one; a tested old revision and a compatible new\none coexist honestly (plan P6.4)."},"tier":{"$ref":"#/components/schemas/McpCatalogTierView","description":"Serialised as `verified|unverified|unsupported` (internally `tested` = verified)."},"transport":{"$ref":"#/components/schemas/McpTransport"},"unavailable_reason":{"type":["string","null"],"description":"Humanised reason an unsupported revision cannot be used."},"unsupported_detail":{"type":["string","null"]},"unsupported_reason":{"oneOf":[{"$ref":"#/components/schemas/McpCatalogGateCode"},{"type":"null"}]},"updated_at":{"type":"string","format":"date-time"},"upstream_status":{"type":"string","description":"Upstream `status` label — sync merges on this, never on `isLatest`."},"verified":{"type":"boolean","description":"This exact revision is Verified (its internal tier is `tested`)."},"version":{"type":"string"},"warnings":{"type":"array","items":{"type":"string"}}}},"McpCatalogRuns":{"type":"string","description":"Where a catalog server runs, in the words the UI uses.","enum":["local","hosted"]},"McpCatalogSecretRequirement":{"type":"object","description":"A typed credential *requirement* declared by the catalog (ADR-0057 §8).\n\n`default_value` is the upstream-declared default of a registry argument — a\nnon-secret input default, never a secret value.","required":["name","required","target"],"properties":{"default_value":{"type":["string","null"]},"description":{"type":["string","null"]},"format":{"type":["string","null"]},"is_secret":{"type":"boolean"},"name":{"type":"string"},"required":{"type":"boolean"},"target":{"$ref":"#/components/schemas/McpCatalogSecretTarget"}}},"McpCatalogSecretTarget":{"type":"string","description":"How a declared credential is consumed by a plan.","enum":["environment","header"]},"McpCatalogSource":{"type":"string","description":"Where a catalog entry was discovered (provenance; plan Q1 keeps this field).","enum":["official_registry","forkline","overlay"]},"McpCatalogTier":{"type":"string","description":"Runtime-compatibility tier of a catalog entry or revision (ADR-0057 §4).\n\nA tier is a statement about whether the pinned plan runs in our runners. It is\n**not** a security certification. `tested` exists only together with a stored\nevidence row written by the verification harness (plan P6.2).","enum":["tested","compatible","unsupported"]},"McpCatalogTierView":{"type":"string","description":"How the catalog shows a tier: `verified|unverified|unsupported`. Catalog entries,\nrevisions and plans carry this view; the stored tier names (`tested`, `compatible`) never\nreach a client.","enum":["verified","unverified","unsupported"]},"McpConfig":{"oneOf":[{"allOf":[{"$ref":"#/components/schemas/LocalMcpConfig"},{"type":"object","required":["transport"],"properties":{"transport":{"type":"string","enum":["local"]}}}]},{"allOf":[{"$ref":"#/components/schemas/RemoteHttpMcpConfig"},{"type":"object","required":["transport"],"properties":{"transport":{"type":"string","enum":["remote_http"]}}}]}],"description":"Internally tagged on `transport`, matching the server's stored JSON shape."},"McpHealthRepository":{"type":"object","required":["id","full_name"],"properties":{"full_name":{"type":"string"},"id":{"type":"string","format":"uuid"},"provider":{"type":["string","null"]}}},"McpHealthRow":{"type":"object","description":"One repository of a server and its state there.","required":["repository","state"],"properties":{"field":{"type":["string","null"],"description":"JSON pointer of the field that fixes it."},"platform":{"type":"boolean","description":"True = our side: show a neutral sentence, never `reason`."},"reason":{"type":"string"},"reported_at":{"type":["string","null"],"format":"date-time"},"repository":{"$ref":"#/components/schemas/McpHealthRepository"},"runner_id":{"type":["string","null"],"format":"uuid"},"state":{"$ref":"#/components/schemas/McpState"},"technical_reason":{"type":["string","null"]}}},"McpInstallPlan":{"type":"object","description":"Frozen installation plan (ADR-0057 §3, plan P2.6).\n\nThe compiler writes one per revision; a user-approved upgrade produces a new plan\nwith a new `plan_hash`. `environment`/`headers` values are literal non-secret\ninputs or `{env:SECRET_NAME}` references — never secret values — and the `Debug`\nimpl prints keys only so a plan can never leak a credential through a log line.","required":["kind"],"properties":{"args":{"type":"array","items":{"type":"string"},"description":"The server's own arguments only. The launcher (`npx -y pkg@ver`, `uvx --from ...`)\nis built from `package`, `package_version` and `entrypoint` by\n[`crate::mcp::launch_argv`]."},"bootstrap":{"type":"array","items":{"type":"string"},"description":"Bootstrap steps the platform setup phase must run first (ADR-0057 §7)."},"command":{"type":["string","null"]},"compiler_version":{"type":["string","null"]},"dependency_constraints":{"type":"array","items":{"type":"string"},"description":"Transitive dependency pins (plan R14), e.g. `mcp<2`."},"entrypoint":{"type":["string","null"],"description":"Resolved entrypoint (npm `bin` map / wheel `entry_points.txt`), plan P2.5."},"environment":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"headers":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"kind":{"type":"string","description":"What the plan installs: `npm`, `pypi`, `binary` or `remote`."},"native_addon":{"type":"boolean","description":"Native addon present: needs the pre-install strategy (plan R15)."},"package":{"type":["string","null"],"description":"Package coordinates for a stdio plan."},"package_version":{"type":["string","null"]},"plan_hash":{"type":["string","null"],"description":"sha256 over the canonical plan JSON. Computed without secret values."},"recipe_version":{"type":["string","null"]},"remote_transport":{"type":["string","null"],"description":"Remote protocol for `kind = \"remote\"`: `streamable_http` or `sse`."},"runtime_arguments":{"type":"array","items":{"$ref":"#/components/schemas/McpInstallPlanInput"},"description":"Argument slots the plan exposes (package + runtime arguments)."},"url":{"type":["string","null"]},"version_disagreement":{"type":["string","null"],"description":"Upstream `server.version` disagrees with the pinned package version (plan E1 §4)."},"warnings":{"type":"array","items":{"type":"string"}}}},"McpInstallPlanInput":{"type":"object","description":"A non-secret plan input slot a user may fill (`--input K=V`).","required":["name"],"properties":{"default":{"type":["string","null"]},"description":{"type":["string","null"]},"name":{"type":"string"},"position":{"type":["integer","null"],"description":"Positional slot in `argv`, when the input is an argument rather than an\nenvironment variable.","minimum":0},"required":{"type":"boolean"}}},"McpLaunch":{"type":"object","required":["transport"],"properties":{"args":{"type":"array","items":{"type":"string"}},"command":{"type":["array","null"],"items":{"type":"string"}},"env":{"type":"array","items":{"$ref":"#/components/schemas/McpLaunchValue"}},"headers":{"type":"array","items":{"$ref":"#/components/schemas/McpLaunchValue"}},"opencode_config":{"description":"The server's OpenCode JSON with `{env:NAME}` placeholders, never values."},"package":{"oneOf":[{"$ref":"#/components/schemas/McpLaunchPackage"},{"type":"null"}]},"transport":{"type":"string","description":"`local` or `remote`."},"url":{"type":["string","null"]}}},"McpLaunchPackage":{"type":"object","required":["ecosystem","name","version"],"properties":{"ecosystem":{"type":"string"},"name":{"type":"string"},"version":{"type":"string"}}},"McpLaunchValue":{"type":"object","description":"One env or header value of a launch view. A secret is its name, never its value.","required":["key","kind","text"],"properties":{"key":{"type":"string"},"kind":{"type":"string","description":"`plain`, `secret` or `missing`."},"prefix":{"type":["string","null"]},"scope":{"type":["string","null"]},"text":{"type":"string"}}},"McpMatched":{"type":"object","required":["count","names"],"properties":{"count":{"type":"integer","format":"int64"},"names":{"type":"array","items":{"type":"string"},"description":"The first three `owner/name`."}}},"McpParseProblem":{"type":"object","required":["message","blocking"],"properties":{"blocking":{"type":"boolean"},"message":{"type":"string"}}},"McpPreviewSide":{"type":"object","required":["version","tier","launch","publisher"],"properties":{"launch":{"$ref":"#/components/schemas/McpLaunch"},"publisher":{"type":"string"},"tier":{"$ref":"#/components/schemas/McpCatalogTierView"},"version":{"type":"string"}}},"McpRawRow":{"type":"object","description":"A server from `opencode_config.mcp`, read only.","required":["key","origin","config"],"properties":{"config":{},"key":{"type":"string"},"origin":{"type":"string","description":"`account` or `repository`."},"shadowed_by":{"oneOf":[{"$ref":"#/components/schemas/McpShadowedBy"},{"type":"null"}]}}},"McpRepositoryRef":{"type":"object","required":["id","full_name"],"properties":{"full_name":{"type":"string"},"id":{"type":"string","format":"uuid"}}},"McpRepositoryWarning":{"type":"object","required":["server_id","slug","kind","message"],"properties":{"field":{"type":["string","null"]},"kind":{"type":"string"},"message":{"type":"string"},"server_id":{"type":"string","format":"uuid"},"slug":{"type":"string"}}},"McpRequirement":{"type":"object","required":["name","label","secret","required"],"properties":{"default":{"type":["string","null"]},"description":{"type":["string","null"]},"label":{"type":"string"},"name":{"type":"string"},"required":{"type":"boolean"},"secret":{"type":"boolean"}}},"McpSecretHint":{"type":"object","required":["field","key"],"properties":{"field":{"type":"string","description":"`environment` or `headers`."},"key":{"type":"string"}}},"McpServer":{"type":"object","required":["id","name","slug","enabled","generation","repositories","source","status","matched","launch","summary","created_at","updated_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"credential_bindings":{"type":"object","description":"`NAME` -> `account/NAME` or `repo/NAME`.","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"enabled":{"type":"boolean"},"generation":{"type":"integer","format":"int64"},"id":{"type":"string","format":"uuid"},"inputs":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"launch":{"$ref":"#/components/schemas/McpLaunch"},"matched":{"$ref":"#/components/schemas/McpMatched"},"name":{"type":"string"},"repositories":{"$ref":"#/components/schemas/RepositorySelector"},"requirements":{"type":"array","items":{"$ref":"#/components/schemas/McpRequirement"}},"slug":{"type":"string"},"source":{"$ref":"#/components/schemas/McpServerSource"},"status":{"$ref":"#/components/schemas/McpServerStatus"},"summary":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}}},"McpServerListItem":{"type":"object","required":["id","name","slug","enabled","generation","source","summary","repositories","repository_count","matched","status"],"properties":{"enabled":{"type":"boolean"},"generation":{"type":"integer","format":"int64"},"id":{"type":"string","format":"uuid"},"matched":{"$ref":"#/components/schemas/McpMatched"},"name":{"type":"string"},"repositories":{"$ref":"#/components/schemas/RepositorySelector"},"repository_count":{"type":"integer","format":"int64"},"slug":{"type":"string"},"source":{"$ref":"#/components/schemas/McpServerListSource"},"status":{"$ref":"#/components/schemas/McpServerStatus"},"summary":{"type":"string"}}},"McpServerListSource":{"oneOf":[{"type":"object","required":["title","version","tier","kind"],"properties":{"kind":{"type":"string","enum":["catalog"]},"tier":{"$ref":"#/components/schemas/McpCatalogTierView"},"title":{"type":"string"},"version":{"type":"string"}}},{"type":"object","required":["transport","kind"],"properties":{"kind":{"type":"string","enum":["custom"]},"transport":{"type":"string","description":"`local` or `remote`."}}}]},"McpServerRepositoriesResponse":{"type":"object","description":"`GET /mcp-servers/{id}/repositories`.","required":["items","total"],"properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/McpHealthRow"}},"next_offset":{"type":["integer","null"],"format":"int64"},"total":{"type":"integer","format":"int64"}}},"McpServerSource":{"oneOf":[{"type":"object","required":["entry_id","external_id","title","version","tier","kind"],"properties":{"entry_available":{"type":"boolean"},"entry_id":{"type":"string","format":"uuid"},"external_id":{"type":"string"},"kind":{"type":"string","enum":["catalog"]},"latest_tier":{"oneOf":[{"$ref":"#/components/schemas/McpCatalogTierView"},{"type":"null"}]},"latest_version":{"type":["string","null"]},"plan_hash":{"type":["string","null"]},"tier":{"$ref":"#/components/schemas/McpCatalogTierView"},"title":{"type":"string"},"version":{"type":"string"}}},{"type":"object","required":["config","kind"],"properties":{"config":{"$ref":"#/components/schemas/McpConfig"},"kind":{"type":"string","enum":["custom"]}}}],"description":"Where a server comes from. Catalog servers are pinned to a revision."},"McpServerStatus":{"type":"object","required":["state","repositories_total","repositories_ok","repositories_failing","repositories_needs_setup","repositories_not_running","repositories_not_used"],"properties":{"last_reported_at":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]},"repositories_failing":{"type":"integer","format":"int64"},"repositories_needs_setup":{"type":"integer","format":"int64"},"repositories_not_running":{"type":"integer","format":"int64"},"repositories_not_used":{"type":"integer","format":"int64"},"repositories_ok":{"type":"integer","format":"int64"},"repositories_total":{"type":"integer","format":"int64"},"since":{"type":["string","null"],"format":"date-time"},"stage":{"type":["string","null"],"description":"`render`, `fetch`, `install`, `apply`, `connect` or `remove`."},"state":{"$ref":"#/components/schemas/McpState"},"top_problem":{"oneOf":[{"$ref":"#/components/schemas/McpTopProblem"},{"type":"null"}]}}},"McpShadowedBy":{"type":"object","required":["kind"],"properties":{"kind":{"type":"string","description":"`server` or `repository`."},"name":{"type":["string","null"]},"server_id":{"type":["string","null"],"format":"uuid"}}},"McpState":{"type":"string","description":"The six statuses a user sees. `unavailable` is \"Not running\" (our side).","enum":["working","failing","needs_setup","unavailable","not_used_yet","off"]},"McpToolCallProbe":{"type":"object","description":"The authenticated `tools/call` that earns a `tested` tier (ADR-0057 §4: connected\nis not authorized).\n\nArguments and responses can embed resolved credentials, so `Debug` prints argument\nkeys only and redacts the response.","required":["tool"],"properties":{"actual":{"type":["string","null"]},"args":{},"expected_pattern":{"type":["string","null"]},"tool":{"type":"string"}}},"McpTopProblem":{"type":"object","required":["kind","repository"],"properties":{"field":{"type":["string","null"]},"kind":{"type":"string","description":"`failing`, `needs_setup` or `platform`."},"more":{"type":"integer","format":"int64","description":"Other repositories with the same kind."},"reason":{"type":"string","description":"Empty for `platform`."},"repository":{"$ref":"#/components/schemas/McpRepositoryRef"}}},"McpTransport":{"type":"string","description":"Transport type for an MCP server.","enum":["local","remote_http"]},"McpUpgradePreview":{"type":"object","description":"`GET /mcp-servers/{id}/upgrade-preview?version=`.","required":["from","to","package_changed","publisher_changed"],"properties":{"from":{"$ref":"#/components/schemas/McpPreviewSide"},"package_changed":{"type":"boolean"},"publisher_changed":{"type":"boolean"},"requirements_added":{"type":"array","items":{"$ref":"#/components/schemas/McpRequirement"}},"requirements_removed":{"type":"array","items":{"$ref":"#/components/schemas/McpRequirement"}},"to":{"$ref":"#/components/schemas/McpPreviewSide"},"versions":{"type":"array","items":{"$ref":"#/components/schemas/McpVersionOption"},"description":"Installable versions, newest first, the current one excluded."}}},"McpVerificationProbe":{"type":"object","description":"One named probe result of a verification run (plan P3.7/P6.2).","required":["name","status"],"properties":{"duration_ms":{"type":["integer","null"],"format":"int64"},"error":{"type":["string","null"]},"name":{"type":"string"},"status":{"type":"string","description":"`passed`, `failed` or `skipped`."}}},"McpVersionOption":{"type":"object","required":["version","tier","latest"],"properties":{"latest":{"type":"boolean"},"tier":{"$ref":"#/components/schemas/McpCatalogTierView"},"version":{"type":"string"}}},"Model":{"type":"object","required":["id","name"],"properties":{"cost":{"oneOf":[{"$ref":"#/components/schemas/ModelCost"},{"type":"null"}]},"deprecated":{"type":"boolean"},"family":{"type":["string","null"]},"id":{"type":"string"},"is_free":{"type":"boolean"},"limit":{"oneOf":[{"$ref":"#/components/schemas/ModelLimit"},{"type":"null"}]},"name":{"type":"string"},"reasoning":{"type":"boolean"},"tool_call":{"type":"boolean"}}},"ModelCost":{"type":"object","properties":{"cache_read":{"type":["number","null"],"format":"double"},"cache_write":{"type":["number","null"],"format":"double"},"input":{"type":"number","format":"double"},"output":{"type":"number","format":"double"}}},"ModelLimit":{"type":"object","properties":{"context":{"type":"integer","format":"int32","minimum":0},"output":{"type":["integer","null"],"format":"int32","minimum":0}}},"NewMcpServerSource":{"oneOf":[{"type":"object","required":["catalog"],"properties":{"catalog":{"type":"object","required":["entry"],"properties":{"entry":{"type":"string","description":"External id, slug or entry UUID."},"version":{"type":["string","null"],"description":"The latest installable version when omitted."}}}}},{"type":"object","required":["custom"],"properties":{"custom":{"type":"object","required":["config"],"properties":{"config":{"$ref":"#/components/schemas/McpConfig"}}}}}],"description":"`POST /mcp-servers` `source`."},"OnConflict":{"type":"string","enum":["replace","skip"]},"OpencodeConfigResponse":{"type":"object","properties":{"config":{}}},"ParseMcpServersRequest":{"type":"object","description":"`POST /mcp-servers/parse` body.","required":["text"],"properties":{"text":{"type":"string"}}},"ParseMcpServersResponse":{"type":"object","required":["format","servers"],"properties":{"format":{"type":"string","description":"`claude_code`, `cursor`, `vscode`, `opencode` or `unknown`."},"servers":{"type":"array","items":{"$ref":"#/components/schemas/ParsedMcpServer"}}}},"ParsedMcpServer":{"type":"object","required":["key","name","slug"],"properties":{"config":{"oneOf":[{"$ref":"#/components/schemas/McpConfig","description":"`None` when the server cannot be represented."},{"type":"null"}]},"credential_bindings":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"key":{"type":"string"},"name":{"type":"string"},"problems":{"type":"array","items":{"$ref":"#/components/schemas/McpParseProblem"}},"secret_hints":{"type":"array","items":{"$ref":"#/components/schemas/McpSecretHint"}},"slug":{"type":"string"}}},"PredictedOutcome":{"type":"string","description":"What a test or backtest predicts.","enum":["would_run","would_run_unverified","filtered","condition_error","template_error","error"]},"Provenance":{"type":"string","description":"Where a drafted spec value came from: `fromEvent` (taken from the event) or `suggested` (added by Forkline; check it).","enum":["fromEvent","suggested"]},"ProvenanceEntry":{"type":"object","required":["pointer","kind","note"],"properties":{"fact":{"type":["string","null"]},"kind":{"$ref":"#/components/schemas/Provenance"},"note":{"type":"string"},"pointer":{"type":"string"}}},"Provider":{"type":"object","required":["id","name","models"],"properties":{"doc":{"type":["string","null"]},"id":{"type":"string"},"models":{"type":"array","items":{"$ref":"#/components/schemas/Model"}},"name":{"type":"string"}}},"ProviderInfo":{"type":"object","required":["id","name"],"properties":{"doc":{"type":["string","null"]},"id":{"type":"string"},"name":{"type":"string"}}},"RateLimitResponse":{"type":"object","required":["error","code","retry_after_secs"],"properties":{"code":{"type":"string"},"error":{"type":"string"},"retry_after_secs":{"type":"integer","format":"int64","minimum":0}}},"RecentEvent":{"allOf":[{"$ref":"#/components/schemas/EventHeadline"},{"type":"object","required":["summary","reactions","reactions_total"],"properties":{"reactions":{"type":"array","items":{"$ref":"#/components/schemas/EventReaction"}},"reactions_total":{"type":"integer","format":"int64"},"summary":{"description":"The stored event summary (camelCase document, at most 4 KiB)."}}}]},"RecentEventDetail":{"allOf":[{"$ref":"#/components/schemas/RecentEvent"},{"type":"object","required":["facts"],"properties":{"facts":{"type":"array","items":{"$ref":"#/components/schemas/EventFact"}}}}]},"RemoteHttpMcpConfig":{"type":"object","required":["url"],"properties":{"headers":{"type":"object","additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"timeout_ms":{"type":"integer","format":"int32","minimum":0},"url":{"type":"string"}}},"Repository":{"type":"object","required":["id","user_id","connector_id","owner","name","repository_url","trigger_policy","allowed_users","created_at","updated_at"],"properties":{"allowed_users":{"type":"array","items":{"type":"string"}},"auto_fix_ci":{"type":["boolean","null"]},"auto_fix_max_attempts":{"type":["integer","null"],"format":"int32"},"auto_fix_merge_conflicts":{"type":["boolean","null"]},"auto_fix_merge_conflicts_max_attempts":{"type":["integer","null"],"format":"int32"},"auto_pr_review":{"type":["boolean","null"]},"auto_pr_review_action":{"oneOf":[{"$ref":"#/components/schemas/AutoPrReviewAction"},{"type":"null"}]},"auto_pr_review_prompt":{"type":["string","null"]},"auto_pr_review_scope":{"oneOf":[{"$ref":"#/components/schemas/AutoPrReviewScope"},{"type":"null"}]},"connector_id":{"type":"string","format":"uuid"},"created_at":{"type":"string","format":"date-time"},"default_model":{"type":["string","null"]},"default_runner_size":{"oneOf":[{"$ref":"#/components/schemas/RunnerSize"},{"type":"null"}]},"deleted_at":{"type":["string","null"],"format":"date-time"},"id":{"type":"string","format":"uuid"},"max_active_runners":{"type":["integer","null"],"format":"int32"},"name":{"type":"string"},"opencode_config":{},"owner":{"type":"string"},"repository_url":{"type":"string"},"trigger_policy":{"$ref":"#/components/schemas/TriggerPolicy"},"updated_at":{"type":"string","format":"date-time"},"user_id":{"type":"string","format":"uuid"}}},"RepositoryMcpServerEntry":{"type":"object","required":["server_id","name","slug","summary","status"],"properties":{"name":{"type":"string"},"server_id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"status":{"$ref":"#/components/schemas/McpServerStatus","description":"This repository only."},"summary":{"type":"string"}}},"RepositoryMcpServers":{"type":"object","description":"`GET /repositories/{id}/mcp-servers`: the effective view.","required":["repository","servers"],"properties":{"raw":{"type":"array","items":{"$ref":"#/components/schemas/McpRawRow"}},"repository":{"$ref":"#/components/schemas/McpRepositoryRef"},"servers":{"type":"array","items":{"$ref":"#/components/schemas/RepositoryMcpServerEntry"}},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/McpRepositoryWarning"}}}},"RepositoryRef":{"type":"object","required":["full_name"],"properties":{"full_name":{"type":"string"},"id":{"type":["string","null"],"format":"uuid"}}},"RepositorySecret":{"type":"object","required":["id","repository_id","name","created_at","updated_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"repository_id":{"type":"string","format":"uuid"},"updated_at":{"type":"string","format":"date-time"}}},"RepositorySelector":{"type":"object","description":"Which repositories a server (or any other selector user) reaches.","required":["include"],"properties":{"exclude":{"type":["array","null"],"items":{"$ref":"#/components/schemas/RepositorySelectorEntry"}},"include":{"type":"object","description":"`\"all\"` or a list of selectors."}},"additionalProperties":false},"RepositorySelectorEntry":{"type":"object","description":"`{ id }` or `{ name: \"owner/glob\" }`.","properties":{"id":{"type":["string","null"],"format":"uuid"},"name":{"type":["string","null"]}},"additionalProperties":false},"RepositorySort":{"type":"string","enum":["updated","name","connector"]},"RepositoryStatus":{"type":"string","enum":["all","active","disabled"]},"ResolvedRepositories":{"type":"object","required":["count","all","sample"],"properties":{"all":{"type":"boolean"},"count":{"type":"integer","format":"int64"},"sample":{"type":"array","items":{"$ref":"#/components/schemas/RepositoryRef"}}}},"RoutineResponse":{"type":"object","required":["id","name","spec","status","created_at","updated_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"description":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"last_run":{"oneOf":[{"$ref":"#/components/schemas/LastRun","description":"The most recent run record. Absent when not requested; `null` when the routine has\nnot run."},{"type":"null"}]},"name":{"type":"string"},"published_at":{"type":["string","null"],"format":"date-time"},"repository_count":{"type":["integer","null"],"format":"int64","description":"How many repositories the routine currently selects. Present on the list and on the\ndetail response."},"spec":{"description":"The routine definition (version 2): `on`, `repositories`, `filters`, `agent`, `limits`."},"status":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"webhook_secret":{"type":["string","null"],"description":"The signing secret of an `on.webhook` routine, shown only in the response that\ncreated or rotated it. Store it then: it cannot be read again."},"webhook_secret_configured":{"type":"boolean","description":"Whether an `on.webhook` routine has its signing secret."},"webhook_secret_origin":{"oneOf":[{"$ref":"#/components/schemas/WebhookSecretOrigin","description":"Who chose the stored secret: `generated` (Forkline made it) or `provided` (the owner\npasted the vendor's). `null` when no secret is stored. The secret itself is never returned\nfor a provided origin."},{"type":"null"}]},"webhook_secret_updated_at":{"type":["string","null"],"format":"date-time","description":"When the stored secret was generated, rotated or pasted."}}},"RoutineRun":{"type":"object","required":["id","routine_id","event","trigger_source","outcome","reason","trace","aggregated_count","created_at"],"properties":{"aggregated_count":{"type":"integer","format":"int32"},"created_at":{"type":"string","format":"date-time"},"event":{"$ref":"#/components/schemas/EventHeadline"},"event_id":{"type":["string","null"],"format":"uuid","description":"The event that started the run. It may have been evicted since (the newest 5,000 per\naccount are kept); the event endpoint then answers 404."},"id":{"type":"string","format":"uuid"},"issue_number":{"type":["integer","null"],"format":"int64"},"outcome":{"$ref":"#/components/schemas/RunOutcome"},"pr_number":{"type":["integer","null"],"format":"int64"},"reason":{"type":"string"},"repository":{"oneOf":[{"$ref":"#/components/schemas/RepositoryRef"},{"type":"null"}]},"routine_id":{"type":"string","format":"uuid"},"stage":{"oneOf":[{"$ref":"#/components/schemas/Stage"},{"type":"null"}]},"task":{"oneOf":[{"$ref":"#/components/schemas/RunTask"},{"type":"null"}]},"trace":{"type":"array","items":{"$ref":"#/components/schemas/TraceEntry"}},"trigger_source":{"$ref":"#/components/schemas/TriggerSource"},"window_ended_at":{"type":["string","null"],"format":"date-time"},"window_started_at":{"type":["string","null"],"format":"date-time"}}},"RunCounts":{"type":"object","required":["ran","skipped","limited","errors"],"properties":{"errors":{"type":"integer","format":"int64"},"limited":{"type":"integer","format":"int64"},"ran":{"type":"integer","format":"int64"},"skipped":{"type":"integer","format":"int64"}}},"RunEstimate":{"type":"object","description":"The most credits a run may use, and how many runs would start.","required":["runs","credits_per_run_max","credits_max"],"properties":{"credits_max":{"type":"integer","format":"int64","description":"`credits_per_run_max * runs`."},"credits_per_run_max":{"type":"integer","format":"int64"},"runs":{"type":"integer","format":"int64","description":"Targets that start a run (not blocked by a filter).","minimum":0}}},"RunOutcome":{"type":"string","description":"How a run ended. `superseded` is derived when read and never stored.","enum":["task_created","superseded","filtered","deduplicated","skipped_active","concurrency_limited","run_limit","credit_exhausted","fan_out_refused","template_error","condition_error","dropped_overload","error"]},"RunRoutineRequest":{"type":"object","description":"`POST /routines/{id}/run`: start a routine now, or preview what it would do. An unknown\nfield is refused (a typo such as `repository` must not start a run on every repository).","properties":{"dry_run":{"type":"boolean","description":"Evaluate and render only: nothing is written and no run starts."},"event_id":{"type":["string","null"],"format":"uuid","description":"Event routines: the stored event (`routine_events.id`, source `event`) to replay.\nRequired for event routines, not allowed for other triggers."},"payload":{"description":"Webhook routines: the body a delivery would carry (default `{}`, at most 5 MiB, like a webhook).\nNot allowed for other triggers."},"repositories":{"type":["array","null"],"items":{"type":"string","format":"uuid"},"description":"Webhook and schedule routines: a subset of the routine's selected repositories\n(default: all of them). Not allowed for event routines."}},"additionalProperties":false},"RunRoutineResponse":{"type":"object","properties":{"dry_run":{"type":"boolean"},"estimate":{"$ref":"#/components/schemas/RunEstimate"},"event_id":{"type":["string","null"],"format":"uuid","description":"The `routine_events` row of a real run, see `GET /v1/routines/events/{event_id}`."},"not_evaluated":{"type":"array","items":{"$ref":"#/components/schemas/RuntimeCheck"},"description":"Dry run only: the checks that only happen at run time."},"reason":{"type":["string","null"],"description":"Real run only: why no task was created, when none was."},"session_urls":{"type":"array","items":{"type":"string"}},"targets":{"type":"array","items":{"$ref":"#/components/schemas/RunTarget"}},"task_ids":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Real run only: the tasks created."}}},"RunTarget":{"type":"object","description":"One repository of a manual run. A dry run fills the verdict fields, a real run fills\n`outcome`, `task_id` and `session_url`.","required":["repository"],"properties":{"decisive_stage":{"oneOf":[{"$ref":"#/components/schemas/Stage"},{"type":"null"}]},"not_stored":{"type":"array","items":{"type":"string"},"description":"Event replay dry run only: the fields the prompt, ref, `when` or `paths` read that the\nevent store does not keep. A real run of this replay is refused with 422\n`event_fields_not_stored`."},"outcome":{"oneOf":[{"$ref":"#/components/schemas/RunOutcome","description":"Real run only: what happened on this repository."},{"type":"null"}]},"predicted_outcome":{"oneOf":[{"$ref":"#/components/schemas/PredictedOutcome","description":"Dry run only."},{"type":"null"}]},"reason":{"type":["string","null"]},"rendered_prompt":{"type":["string","null"],"description":"The prompt as it would be sent, cut to 64 KiB. Dry run only."},"rendered_ref":{"type":["string","null"]},"repository":{"$ref":"#/components/schemas/RepositoryRef"},"session_url":{"type":["string","null"],"description":"Real run only: `/sessions/<id>`."},"stages":{"type":"array","items":{"$ref":"#/components/schemas/TestStage"},"description":"Every stage in order. Dry run only (empty for a real run)."},"task_id":{"type":["string","null"],"format":"uuid","description":"Real run only."}}},"RunTask":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string"},"superseded_by_task_id":{"type":["string","null"],"format":"uuid"}}},"Runner":{"type":"object","required":["id","short","repository_id","name","status","source","size","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"git_ref":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"model":{"type":["string","null"]},"name":{"type":"string"},"opencode_session_id":{"type":["string","null"]},"repository_id":{"type":"string","format":"uuid"},"session_context":{"type":["string","null"]},"short":{"type":"string"},"size":{"$ref":"#/components/schemas/RunnerSize"},"source":{"$ref":"#/components/schemas/RunnerSource"},"started_at":{"type":["string","null"],"format":"date-time"},"status":{"$ref":"#/components/schemas/RunnerStatus"},"stopped_at":{"type":["string","null"],"format":"date-time"},"stopped_reason":{"oneOf":[{"$ref":"#/components/schemas/StoppedReason"},{"type":"null"}]},"user_message":{"type":["string","null"]}}},"RunnerEventResponse":{"type":"object","required":["id","runner_id","event_type","details","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"details":{},"event_type":{"type":"string"},"id":{"type":"string","format":"uuid"},"new_status":{"type":["string","null"]},"previous_status":{"type":["string","null"]},"runner_id":{"type":"string","format":"uuid"}}},"RunnerSettingsResponse":{"type":"object","required":["runner_id","settings","updated_at"],"properties":{"runner_id":{"type":"string","format":"uuid"},"settings":{},"updated_at":{"type":"string","format":"date-time"}}},"RunnerSize":{"type":"string","enum":["basic","advanced","pro"]},"RunnerSizeSpec":{"type":"object","required":["id","name","cpu","ram","multiplier"],"properties":{"cpu":{"type":"integer","format":"int32","minimum":0},"id":{"$ref":"#/components/schemas/RunnerSize"},"multiplier":{"type":"integer","format":"int32","minimum":0},"name":{"type":"string"},"ram":{"type":"string"}}},"RunnerSource":{"type":"string","enum":["manual","autonomous"]},"RunnerStatus":{"type":"string","enum":["pending","starting","running","stopping","stopped","failed"]},"RuntimeCheck":{"type":"string","description":"A check that needs live state and so is not evaluated by test or backtest.","enum":["event_key","concurrency","run_limit","credits"]},"ScheduleEstimate":{"type":"object","required":["runs_per_week","next_runs","repositories"],"properties":{"next_runs":{"type":"array","items":{"type":"string","format":"date-time"}},"repositories":{"type":"integer","format":"int64"},"runs_per_week":{"type":"number","format":"double"}}},"SecretUsedBy":{"type":"object","description":"An MCP server that binds a secret.","required":["server_id","name"],"properties":{"name":{"type":"string"},"server_id":{"type":"string","format":"uuid"}}},"SetWebhookSecretRequest":{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","description":"The vendor's signing secret, 16 to 512 bytes."}}},"Stage":{"type":"string","description":"The named steps of handling one event for one routine, in the order they run.","enum":["overload","fan_out","event","repository","self_guard","bots","draft","fork","branches","labels","authors","command","paths","when","trigger_policy","template","event_key","concurrency","run_limit","credits","submit"]},"StageResult":{"type":"string","description":"The result of one stage. `NotEvaluated` is used only by test and backtest.","enum":["pass","filtered","error","not_applicable","not_evaluated"]},"StartRunnerRequest":{"type":"object","description":"Request to start a new runner.","required":["name"],"properties":{"initial_prompt":{"type":["string","null"],"description":"Initial prompt for a one-shot autonomous runner.\nWhen provided, creates an autonomous runner that executes this prompt\nand shuts down when complete."},"model":{"type":["string","null"],"description":"Default model for OpenCode (optional, defaults to project or user preference)\nFormat: \"provider/model-name\" (e.g., \"anthropic/claude-sonnet-4-5\")"},"name":{"type":"string","description":"Runner name"},"size":{"oneOf":[{"$ref":"#/components/schemas/RunnerSize","description":"Runner size (optional, defaults to project or user preference)"},{"type":"null"}]}}},"StoppedReason":{"type":"string","enum":["manual","idle_timeout","credit_exhaustion","error","pr_merged","pr_closed","stale_pre_execution"]},"SubscriptionCreditsInfo":{"type":"object","required":["plan_name","status","period_credits_remaining","period_ends_at","daily_credits","billing_period_end"],"properties":{"billing_period_end":{"type":"string","format":"date-time"},"cancel_at":{"type":["string","null"],"format":"date-time"},"daily_credits":{"type":"integer","format":"int64"},"period_credits_remaining":{"type":"integer","format":"int64"},"period_ends_at":{"type":"string","format":"date-time"},"plan_name":{"type":"string"},"status":{"type":"string"}}},"TaskDetailResponse":{"type":"object","required":["id","status","task_type","repository_url","prompt","attempt_count","created_at"],"properties":{"attempt_count":{"type":"integer","format":"int32"},"completed_at":{"type":["string","null"],"format":"date-time"},"context":{},"created_at":{"type":"string","format":"date-time"},"error_message":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"platform_result":{},"prompt":{"type":"string"},"repository_url":{"type":"string"},"result_data":{},"result_type":{"type":["string","null"]},"runner_id":{"type":["string","null"],"format":"uuid"},"started_at":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"task_type":{"type":"string"}}},"TaskSummary":{"type":"object","required":["id","status","task_type","repository_url","created_at"],"properties":{"completed_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"error_message":{"type":["string","null"]},"id":{"type":"string","format":"uuid"},"repository_url":{"type":"string"},"result_type":{"type":["string","null"]},"started_at":{"type":["string","null"],"format":"date-time"},"status":{"type":"string"},"task_type":{"type":"string"}}},"TestRoutineRequest":{"type":"object","required":["source"],"properties":{"name":{"type":["string","null"]},"source":{"$ref":"#/components/schemas/TestSource"},"spec":{}}},"TestRoutineResponse":{"type":"object","required":["source_type","stages","predicted_outcome","reason","unverified_fields","not_evaluated"],"properties":{"decisive_stage":{"oneOf":[{"$ref":"#/components/schemas/Stage"},{"type":"null"}]},"event":{"oneOf":[{"$ref":"#/components/schemas/EventHeadline"},{"type":"null"}]},"not_evaluated":{"type":"array","items":{"$ref":"#/components/schemas/RuntimeCheck"}},"predicted_outcome":{"$ref":"#/components/schemas/PredictedOutcome"},"reason":{"type":"string"},"rendered_prompt":{"type":["string","null"]},"rendered_ref":{"type":["string","null"]},"repository":{"oneOf":[{"$ref":"#/components/schemas/RepositoryRef"},{"type":"null"}]},"source_type":{"type":"string"},"stages":{"type":"array","items":{"$ref":"#/components/schemas/TestStage"}},"summary":{},"unverified_fields":{"type":"array","items":{"type":"string"}}}},"TestSource":{"oneOf":[{"type":"object","required":["event_id","type"],"properties":{"event_id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["recent_event"]}}},{"type":"object","required":["forge","event_header","payload","type"],"properties":{"delivery_id":{"type":["string","null"]},"event_header":{"type":"string"},"forge":{"type":"string"},"payload":{},"type":{"type":"string","enum":["payload"]}}},{"type":"object","required":["repository_id","type"],"properties":{"repository_id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["repository"]}}},{"type":"object","required":["repository_id","body","type"],"properties":{"body":{},"repository_id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["webhook_body"]}}}],"description":"What to test a routine against."},"TestStage":{"allOf":[{"$ref":"#/components/schemas/TraceEntry"},{"type":"object","required":["reason","decisive"],"properties":{"decisive":{"type":"boolean"},"reason":{"type":"string"}}}]},"TraceEntry":{"type":"object","required":["stage","field","observed","rule","result"],"properties":{"field":{"type":"string","description":"A document path such as `pr.baseBranch`."},"observed":{"type":"string"},"result":{"$ref":"#/components/schemas/StageResult"},"rule":{"type":"string"},"stage":{"$ref":"#/components/schemas/Stage"}}},"TriggerPolicy":{"type":"string","enum":["collaborators","owner_only","allowlist","anyone"]},"TriggerSource":{"type":"string","description":"What started a run: a forge event, the schedule, a custom webhook call or a manual run (`Run now`).","enum":["event","schedule","webhook","manual"]},"UpdateAccountSecretDescriptionRequest":{"type":"object","description":"Metadata-only patch.","properties":{"description":{"type":["string","null"]}}},"UpdateAllSettingsRequest":{"type":"object","properties":{"auto_fix_ci":{"type":["boolean","null"]},"auto_fix_max_attempts":{"type":["integer","null"],"format":"int32"},"auto_fix_merge_conflicts":{"type":["boolean","null"]},"auto_fix_merge_conflicts_max_attempts":{"type":["integer","null"],"format":"int32"},"auto_pr_review":{"type":["boolean","null"]},"auto_pr_review_action":{"oneOf":[{"$ref":"#/components/schemas/AutoPrReviewAction"},{"type":"null"}]},"auto_pr_review_prompt":{"type":["string","null"]},"auto_pr_review_scope":{"oneOf":[{"$ref":"#/components/schemas/AutoPrReviewScope"},{"type":"null"}]},"default_model":{"type":["string","null"]},"default_runner_size":{"oneOf":[{"$ref":"#/components/schemas/RunnerSize"},{"type":"null"}]},"max_active_runners":{"type":["integer","null"],"format":"int32"}}},"UpdateMcpServerRequest":{"type":"object","description":"`PATCH /mcp-servers/{id}`: absent fields keep their value.","properties":{"config":{"oneOf":[{"$ref":"#/components/schemas/McpConfig","description":"Custom servers only."},{"type":"null"}]},"credential_bindings":{"type":["object","null"],"additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"enabled":{"type":["boolean","null"]},"generation":{"type":["integer","null"],"format":"int64","description":"Optimistic concurrency: 409 when stale."},"inputs":{"type":["object","null"],"additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"name":{"type":["string","null"]},"repositories":{"oneOf":[{"$ref":"#/components/schemas/RepositorySelector"},{"type":"null"}]},"slug":{"type":["string","null"]}}},"UpdateOpencodeConfigRequest":{"type":"object","required":["config"],"properties":{"config":{}}},"UpdateRepositoryRequest":{"type":"object","description":"Request to update a repository.","properties":{"allowed_users":{"type":["array","null"],"items":{"type":"string"}},"auto_fix_ci":{"type":["boolean","null"]},"auto_fix_max_attempts":{"type":["integer","null"],"format":"int32"},"auto_fix_merge_conflicts":{"type":["boolean","null"]},"auto_fix_merge_conflicts_max_attempts":{"type":["integer","null"],"format":"int32"},"auto_pr_review":{"type":["boolean","null"]},"auto_pr_review_action":{"oneOf":[{"$ref":"#/components/schemas/AutoPrReviewAction"},{"type":"null"}]},"auto_pr_review_prompt":{"type":["string","null"]},"auto_pr_review_scope":{"oneOf":[{"$ref":"#/components/schemas/AutoPrReviewScope"},{"type":"null"}]},"default_model":{"type":["string","null"]},"default_runner_size":{"oneOf":[{"$ref":"#/components/schemas/RunnerSize"},{"type":"null"}]},"max_active_runners":{"type":["integer","null"],"format":"int32"},"opencode_config":{},"trigger_policy":{"oneOf":[{"$ref":"#/components/schemas/TriggerPolicy"},{"type":"null"}]}}},"UpdateRoutineRequest":{"type":"object","properties":{"description":{"type":["string","null"]},"name":{"type":["string","null"]},"spec":{}}},"UpdateSecretRequest":{"type":"object","required":["value"],"properties":{"value":{"type":"string"}}},"UpdateSettingsRequest":{"type":"object","description":"Request to update settings.","required":["settings"],"properties":{"settings":{"$ref":"#/components/schemas/Value","description":"New settings (merged with existing)"}}},"UpgradeMcpServerRequest":{"type":"object","description":"`POST /mcp-servers/{id}/upgrade`.","required":["version"],"properties":{"credential_bindings":{"type":["object","null"],"additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"inputs":{"type":["object","null"],"additionalProperties":{"type":"string"},"propertyNames":{"type":"string"}},"version":{"type":"string"}}},"UpsertAccountSecretRequest":{"type":"object","description":"Body for the upsert form of `PUT /me/secrets/{name}`. A value is required: this API\nnever returns one, so a metadata-only update goes through `PATCH`.","required":["value"],"properties":{"description":{"type":["string","null"]},"value":{"type":"string"}}},"UsageBreakdownResponse":{"type":"object","required":["key","input_tokens","output_tokens","reasoning_tokens","cache_read_tokens","cache_write_tokens","total_tokens","runner_hours","sessions_count","cache_ratio","share_percent"],"properties":{"cache_ratio":{"type":"number","format":"double"},"cache_read_tokens":{"type":"integer","format":"int64"},"cache_write_tokens":{"type":"integer","format":"int64"},"input_tokens":{"type":"integer","format":"int64"},"key":{"type":"string"},"model_count":{"type":["integer","null"],"format":"int64"},"model_id":{"type":["string","null"]},"output_tokens":{"type":"integer","format":"int64"},"provider_count":{"type":["integer","null"],"format":"int64"},"provider_id":{"type":["string","null"]},"reasoning_tokens":{"type":"integer","format":"int64"},"repository_count":{"type":["integer","null"],"format":"int64"},"repository_id":{"type":["string","null"],"format":"uuid"},"repository_name":{"type":["string","null"]},"repository_ref":{"type":["string","null"],"format":"uuid"},"runner_hours":{"type":"number","format":"double"},"sessions_count":{"type":"integer","format":"int64"},"share_percent":{"type":"number","format":"double"},"total_tokens":{"type":"integer","format":"int64"}}},"UserSettingsResponse":{"type":"object","required":["settings"],"properties":{"settings":{}}},"ValidateRoutineRequest":{"type":"object","required":["spec"],"properties":{"description":{"type":["string","null"]},"name":{"type":["string","null"]},"spec":{}}},"ValidateRoutineResponse":{"type":"object","required":["valid","repositories","warnings","effective"],"properties":{"effective":{"$ref":"#/components/schemas/EffectiveDefaults"},"repositories":{"$ref":"#/components/schemas/ResolvedRepositories"},"valid":{"type":"boolean","description":"Always true: an invalid spec answers 422 instead."},"warnings":{"type":"array","items":{"$ref":"#/components/schemas/ValidationIssue"}}}},"ValidationErrorResponse":{"type":"object","description":"The body of a 422 response: the document is well-formed JSON but not a valid one.","required":["error","code","errors"],"properties":{"code":{"type":"string"},"error":{"type":"string"},"errors":{"type":"array","items":{"$ref":"#/components/schemas/ValidationIssue"}}}},"ValidationIssue":{"type":"object","description":"One problem with a submitted document, located by a JSON pointer.","required":["pointer","message"],"properties":{"code":{"type":["string","null"],"description":"A stable lower-snake identifier of the problem, such as `unknown_field`. Optional:\nclients must work without it."},"message":{"type":"string"},"pointer":{"type":"string","description":"JSON pointer to the offending value, such as `/filters/labels/include/3`."}}},"Value":{},"WebhookEstimate":{"type":"object","required":["repositories","credits_per_call_max"],"properties":{"credits_per_call_max":{"type":"integer","format":"int64"},"repositories":{"type":"integer","format":"int64"}}},"WebhookSecretOrigin":{"type":"string","description":"Who chose a routine's stored webhook secret.","enum":["generated","provided"]},"WidenSuggestion":{"type":"object","required":["selector","repository_count","repositories_sample","would_run","events","days"],"properties":{"days":{"type":"integer","format":"int32","minimum":0},"events":{"type":"integer","format":"int64"},"repositories_sample":{"type":"array","items":{"$ref":"#/components/schemas/RepositoryRef"}},"repository_count":{"type":"integer","format":"int64"},"selector":{"description":"A repository selector such as `{\"name\": \"...\"}`."},"would_run":{"type":"integer","format":"int64"}}}},"securitySchemes":{"bearer_auth":{"type":"http","scheme":"bearer","description":"Personal Access Token (PAT). Create from the Forkline dashboard."}}},"tags":[{"name":"user","description":"User profile and settings"},{"name":"billing","description":"Billing and credits"},{"name":"repositories","description":"Repository management"},{"name":"runners","description":"Runner management"},{"name":"models","description":"AI models and providers"},{"name":"analytics","description":"Usage analytics"},{"name":"routines","description":"Automation routines"},{"name":"api-tokens","description":"Personal API token management"},{"name":"connectors","description":"Git connector management"},{"name":"secrets","description":"Repository secrets management"},{"name":"custom-providers","description":"Custom AI provider management"},{"name":"mcp","description":"MCP catalog browsing and MCP server management"},{"name":"mcp-secrets","description":"Account-level secret provisioning (references only)"}]}