Dobby Platform API API

The Dobby Platform API provides programmatic access to your AI agents, tasks, approvals, and knowledge base (RAG).

Operations 19

GET /api/v1/agents List agents #
GET /api/v1/agents/{id} Get agent details #
PATCH /api/v1/agents/{id} Update agent #
DELETE /api/v1/agents/{id} Archive agent #
GET /api/v1/integrations List integrations #
GET /api/v1/integrations/{id} Get integration details #
POST /api/v1/tasks Create a task #
POST /api/v1/workloads Create a workload #
GET /api/v1/workloads List workloads #
GET /api/v1/approvals List approvals #
GET /api/v1/approvals/{id} Get approval details #
POST /api/v1/approvals/{id}/action Act on an approval #
POST /api/v1/rag/query Query knowledge base #
POST /api/v1/controls/check Inline control-point check #
POST /api/v1/controls/outcome Record enforcement outcome #
GET /api/v1/tenants/{tenantId}/policies List policies #
POST /api/v1/tenants/{tenantId}/policies Create a policy #
GET /api/api-keys List API keys #
POST /api/api-keys Create API key #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/dobby-ai-com:dobby-platform-api-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

dobby-ai-com-api-openapi.json Raw ↑
{"openapi":"3.0.3","info":{"title":"Dobby Platform API","description":"# Overview\n\nThe Dobby Platform API provides programmatic access to your AI agents, tasks, approvals, and knowledge base (RAG).\n\n## Authentication\n\nAll API requests require authentication via API Key. Include your API key in the Authorization header:\n\n```\nAuthorization: Bearer YOUR_API_KEY\n```\n\n## Rate Limiting\n\nAPI requests are rate limited based on your plan tier:\n- **Free**: 60 requests/minute\n- **Standard**: 100 requests/minute\n- **Pro**: 500 requests/minute\n- **Enterprise**: 2000 requests/minute\n\nRate limit headers are included in all responses:\n- `X-RateLimit-Remaining`: Requests remaining in current window\n- `X-RateLimit-Reset`: Unix timestamp when the window resets\n- `Retry-After`: Seconds to wait before retrying (on 429 response)\n\n## Errors\n\nThe API uses standard HTTP status codes:\n- `200`: Success\n- `400`: Bad Request - Invalid parameters\n- `401`: Unauthorized - Missing or invalid API key\n- `403`: Forbidden - Missing required scope\n- `404`: Not Found - Resource doesn't exist\n- `429`: Too Many Requests - Rate limit exceeded\n- `500`: Internal Server Error","version":"1.0.0","contact":{"name":"Dobby Platform Support","email":"support@dobby.ai"}},"servers":[{"url":"http://dobby-ai.com","description":"Production API"},{"url":"http://localhost:3000","description":"Local Development"}],"tags":[{"name":"Agents","description":"Manage AI agent configurations and settings"},{"name":"Workloads","description":"Register and list workloads (agents/workflows streaming run data into Dobby)"},{"name":"Tasks","description":"Create, manage, and monitor agent tasks"},{"name":"Approvals","description":"Human-in-the-loop approval management"},{"name":"Integrations","description":"Manage connected integrations and services"},{"name":"RAG","description":"Query your knowledge base"},{"name":"Controls","description":"Inline control points — ask for a policy verdict before a risky action, then report what your code did (the adherence loop)"},{"name":"Policies","description":"Author and list policies across the 4-layer hierarchy (Platform → Org → Tenant → Process)"},{"name":"API Keys","description":"Manage API keys for programmatic access"}],"paths":{"/api/v1/agents":{"get":{"tags":["Agents"],"summary":"List agents","description":"Get a list of all agents for your organization","operationId":"listAgents","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["active","draft","archived"]},"description":"Filter by status"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"description":"Number of results to return"},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Number of results to skip"}],"responses":{"200":{"description":"List of agents","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Agent"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}]}},"/api/v1/agents/{id}":{"get":{"tags":["Agents"],"summary":"Get agent details","description":"Get detailed information about a specific agent","operationId":"getAgent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Agent ID"}],"responses":{"200":{"description":"Agent details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Agent"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"bearerAuth":[]}]},"patch":{"tags":["Agents"],"summary":"Update agent","description":"Update agent name, description, or status","operationId":"updateAgent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Agent ID"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":100},"description":{"type":"string","maxLength":500},"status":{"type":"string","enum":["active","draft","archived"]}}}}}},"responses":{"200":{"description":"Agent updated","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Agent"},"message":{"type":"string","example":"Agent updated successfully"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"bearerAuth":[]}]},"delete":{"tags":["Agents"],"summary":"Archive agent","description":"Archive an agent (soft delete)","operationId":"deleteAgent","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Agent ID"}],"responses":{"200":{"description":"Agent archived","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Agent archived successfully"},"data":{"type":"object","properties":{"id":{"type":"string"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"bearerAuth":[]}]}},"/api/v1/integrations":{"get":{"tags":["Integrations"],"summary":"List integrations","description":"Get a list of all connected integrations","operationId":"listIntegrations","parameters":[{"name":"type","in":"query","schema":{"type":"string","enum":["git","task_management","messaging","ai"]},"description":"Filter by integration type"},{"name":"is_active","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Filter by active status"}],"responses":{"200":{"description":"List of integrations","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Integration"}},"total":{"type":"integer","example":3}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}]}},"/api/v1/integrations/{id}":{"get":{"tags":["Integrations"],"summary":"Get integration details","description":"Get detailed information about a specific integration","operationId":"getIntegration","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Integration ID"}],"responses":{"200":{"description":"Integration details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Integration"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"bearerAuth":[]}]}},"/api/v1/tasks":{"post":{"tags":["Tasks"],"summary":"Create a task","description":"Create a new task for an agent to execute","operationId":"createTask","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title"],"properties":{"title":{"type":"string","minLength":1,"maxLength":200,"description":"Task title","example":"Review and fix authentication bug"},"description":{"type":"string","maxLength":2000,"description":"Detailed task description","example":"Users are unable to log in after password reset."},"priority":{"type":"string","enum":["low","medium","high"],"default":"medium","description":"Task priority"},"agent_id":{"type":"string","description":"ID of the agent to assign the task to","example":"agent_abc123"}}}}}},"responses":{"200":{"description":"Task created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"task_id":{"type":"string","example":"task_abc123"},"status":{"type":"string","example":"pending"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}]}},"/api/v1/workloads":{"post":{"tags":["Workloads"],"summary":"Create a workload","description":"Register a new workload (a connector that streams agent/workflow run metadata into Dobby). The tenant is derived from the API key. For `platform=dobby_sdk` with no credentials supplied, the server mints a `dsdk_` bearer token and returns it ONCE in `bearer_token` — store it, it cannot be retrieved later.","operationId":"createWorkload","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["display_name"],"properties":{"display_name":{"type":"string","minLength":1,"maxLength":100,"description":"Human-friendly name shown on the Workloads page","example":"iOS Version Agent"},"platform":{"type":"string","enum":["dobby_sdk","openclaw_otlp","crewai_cloud","langsmith","n8n","github_actions","airflow","snowflake","databricks","cursor","saas"],"default":"dobby_sdk","description":"Source platform of the workload"},"auth_method":{"type":"string","enum":["api_token","oauth","service_account"],"default":"api_token"},"bearer_token":{"type":"string","description":"Upstream platform token (paste mode). Encrypted at rest. Omit for dobby_sdk to have one minted."},"external_credentials_secret_ref":{"type":"string","description":"GCP Secret Manager resource path (projects/*/secrets/*/versions/*). Alternative to bearer_token."},"supports_webhook":{"type":"boolean"},"poll_interval_seconds":{"type":"integer","minimum":15,"maximum":3600},"external_account_id":{"type":"string","maxLength":255}}}}}},"responses":{"201":{"description":"Workload created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"workload":{"type":"object","properties":{"id":{"type":"string","example":"wc_a1b2c3d4e5f6"},"display_name":{"type":"string","example":"iOS Version Agent"},"platform":{"type":"string","example":"dobby_sdk"},"status":{"type":"string","example":"pending_auth"}}},"bearer_token":{"type":"string","description":"Minted dsdk_ token — returned only once (mint mode only).","example":"dsdk_0123456789abcdef0123456789abcdef"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}]},"get":{"tags":["Workloads"],"summary":"List workloads","description":"List the tenant's workloads with a KPI rollup. Tenant derived from the API key.","operationId":"listWorkloads","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100},"description":"Max workloads to return"}],"responses":{"200":{"description":"List of workloads + stats","content":{"application/json":{"schema":{"type":"object","properties":{"workloads":{"type":"array","items":{"type":"object"}},"stats":{"type":"object"},"count":{"type":"integer","example":3}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}]}},"/api/v1/approvals":{"get":{"tags":["Approvals"],"summary":"List approvals","description":"Get a list of pending and resolved approvals","operationId":"listApprovals","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["pending","approved","rejected"]},"description":"Filter by approval status"},{"name":"agent_id","in":"query","schema":{"type":"string"},"description":"Filter by agent"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"description":"Number of results to return"},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Number of results to skip"}],"responses":{"200":{"description":"List of approvals","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Approval"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}]}},"/api/v1/approvals/{id}":{"get":{"tags":["Approvals"],"summary":"Get approval details","description":"Get detailed information about a specific approval","operationId":"getApproval","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Approval ID"}],"responses":{"200":{"description":"Approval details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Approval"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"bearerAuth":[]}]}},"/api/v1/approvals/{id}/action":{"post":{"tags":["Approvals"],"summary":"Act on an approval","description":"Approve or reject a pending approval request","operationId":"actOnApproval","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Approval ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["approve","reject","request_changes"],"description":"The action to take"},"note":{"type":"string","maxLength":1000,"description":"Optional note or feedback"}}}}}},"responses":{"200":{"description":"Action completed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Approval"},"message":{"type":"string","example":"Approval approved successfully"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"bearerAuth":[]}]}},"/api/v1/rag/query":{"post":{"tags":["RAG"],"summary":"Query knowledge base","description":"Search your knowledge base using semantic search","operationId":"queryKnowledgeBase","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["question"],"properties":{"question":{"type":"string","minLength":1,"maxLength":2000,"description":"The question to search for","example":"What are your business hours?"},"max_chunks":{"type":"integer","minimum":1,"maximum":20,"default":5,"description":"Maximum number of relevant chunks to return"},"include_sources":{"type":"boolean","default":true,"description":"Whether to include source document info"}}}}}},"responses":{"200":{"description":"Query results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"sources":{"type":"array","items":{"type":"object","properties":{"document_id":{"type":"string","example":"doc_abc123"},"content_preview":{"type":"string","example":"Our business hours are..."},"similarity":{"type":"number","example":0.89}}}},"metadata":{"type":"object","properties":{"chunks_found":{"type":"integer","example":5},"query_time_ms":{"type":"integer","example":234}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"}},"security":[{"bearerAuth":[]}]}},"/api/v1/controls/check":{"post":{"tags":["Controls"],"summary":"Inline control-point check","description":"Ask for a policy verdict on a tool action BEFORE running it. Authenticates an `sk_live_` API key (`Authorization: Bearer` or `X-API-Key`); org/tenant are resolved from the key — never from the body. Requires the `controls:check` scope (`controls:*` and `*` also pass). The HTTP status IS part of the verdict: 200 = pass/redact, 202 = pause_for_approval, 403 = block (all share the verdict body shape). Your own code is the enforcement point — Dobby only decides.","operationId":"controlsCheck","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tool_name"],"properties":{"tool_name":{"type":"string","minLength":1,"description":"The tool/action about to run","example":"send_external_email"},"tool_arguments":{"type":"object","additionalProperties":true,"description":"Arguments of the attempted action","example":{"to":"someone@example.com"}},"actor":{"type":"object","description":"Defaults to {\"actor_id\": \"sdk\", \"actor_type\": \"ai_agent\"} when omitted","properties":{"actor_id":{"type":"string","example":"billing-agent"},"actor_type":{"type":"string","example":"ai_agent"},"actor_name":{"type":"string"}}},"session_id":{"type":"string"},"trace_id":{"type":"string"},"correlation_id":{"type":"string","description":"Shared id linking this verdict to LLM-call telemetry — echoed back in the verdict"},"workflow_id":{"type":"string"},"reasoning":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Verdict — pass or redact (proceed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlVerdict"}}}},"202":{"description":"Verdict — pause_for_approval (same body shape)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlVerdict"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Verdict — block (same body shape; not an auth error). Distinguish a scope denial: a 403 whose body has `error: insufficient_scope` and NO `action` field means the key lacks `controls:check` — grant the scope, do not treat it as a policy block.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ControlVerdict"}}}},"502":{"description":"Policy engine unavailable or returned an unexpected response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/controls/outcome":{"post":{"tags":["Controls"],"summary":"Record enforcement outcome","description":"Records what your code actually did with a verdict (honored / ignored / remediated) — the write side of the adherence loop. Auth: `sk_live_` API key (`Authorization: Bearer` or `X-API-Key`). Requires the `controls:report` scope (`controls:*` and `*` also pass). Either `honored` or `developer_response` is required. Retries with the same `decision_id` are deduped and return `recorded: false, deduped: true`.","operationId":"controlsOutcome","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"decision_id":{"type":"string","nullable":true,"description":"The verdict's decision_id from /controls/check — enables retry dedup"},"honored":{"type":"boolean","description":"true = your code stopped the denied action; false = it proceeded anyway"},"developer_response":{"type":"string","enum":["honored","ignored","remediated"],"description":"Explicit outcome (takes precedence over `honored`)"},"action_taken":{"type":"string","nullable":true,"example":"stopped"},"detail":{"type":"string","nullable":true},"action":{"type":"string","nullable":true,"description":"The tool/action the verdict was for (denormalized for rollups)"},"verdict":{"type":"string","nullable":true},"actor_id":{"type":"string","nullable":true},"workflow_id":{"type":"string","nullable":true},"correlation_id":{"type":"string","nullable":true,"description":"Shared id linking this outcome to the LLM-call telemetry for the same action"}}}}}},"responses":{"200":{"description":"Outcome recorded (recorded: false + deduped: true on a retried decision_id)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"outcome_id":{"type":"string","example":"peo_abc123def456"},"recorded":{"type":"boolean","example":true},"deduped":{"type":"boolean","example":false}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Key lacks the `controls:report` scope (`error: insufficient_scope`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]}]}},"/api/v1/tenants/{tenantId}/policies":{"get":{"tags":["Policies"],"summary":"List policies","description":"List policies for the tenant scope, optionally filtered by layer (1=Platform, 2=Org, 3=Tenant, 4=Process). Layer 4 requires `workflow_id`. Auth: NextAuth session OR an `sk_live_` API key (`Authorization: Bearer` or `X-API-Key`).","operationId":"listPolicies","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"},"description":"Tenant (workspace) ID"},{"name":"layer","in":"query","schema":{"type":"integer","minimum":1,"maximum":4},"description":"Policy layer filter: 1=Platform, 2=Org, 3=Tenant, 4=Process. Omit for all layers."},{"name":"include_inactive","in":"query","schema":{"type":"string","enum":["1"]},"description":"Pass 1 to include inactive policies"},{"name":"workflow_id","in":"query","schema":{"type":"string"},"description":"Required when layer=4 — the workload (external_workload_id) to scope to"}],"responses":{"200":{"description":"Policies for the requested scope","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"type":"object","properties":{"tenant_id":{"type":"string"},"org_id":{"type":"string"},"layer":{"type":"integer","nullable":true},"count":{"type":"integer","example":3},"policies":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}},"can_edit":{"type":"boolean"}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"}},"security":[{"bearerAuth":[]}]},"post":{"tags":["Policies"],"summary":"Create a policy","description":"Create a user-authored policy. `scope_id` is auto-filled from context when omitted (layer 1 → null, layer 2 → org_id, layer 3 → tenant_id); layer 4 requires an explicit workflow_id. Layer-3 policies are validated stricter-wins against the parent org (422 `policy_looser_than_parent` when looser). Auth: NextAuth session OR an `sk_live_` API key (`Authorization: Bearer` or `X-API-Key`); requires the admin role.","operationId":"createPolicy","parameters":[{"name":"tenantId","in":"path","required":true,"schema":{"type":"string"},"description":"Tenant (workspace) ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["layer","text","severity"],"properties":{"layer":{"type":"integer","minimum":1,"maximum":4,"description":"1=Platform, 2=Org, 3=Tenant, 4=Process"},"scope_id":{"type":"string","nullable":true,"minLength":1,"maxLength":200,"description":"Scope of the policy — auto-filled per layer when omitted; workflow_id for layer 4"},"text":{"type":"string","minLength":1,"maxLength":8000,"description":"The policy text (natural language)","example":"Never send customer PII to external email addresses"},"severity":{"type":"string","enum":["critical","high","medium","low"]},"is_active":{"type":"boolean","default":true}}}}}},"responses":{"201":{"description":"Policy created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"data":{"$ref":"#/components/schemas/Policy"},"inline_enforcement":{"type":"object","description":"Whether the policy compiled into a live inline-enforcement rule for /controls/check"}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"description":"Stricter-wins violation — a parent Org policy on the same topic is stricter (`policy_looser_than_parent`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[{"bearerAuth":[]}]}},"/api/api-keys":{"get":{"tags":["API Keys"],"summary":"List API keys","description":"Get a list of all API keys for your organization (session auth required)","operationId":"listApiKeys","responses":{"200":{"description":"List of API keys","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["API Keys"],"summary":"Create API key","description":"Create a new API key (session auth required). The full key is only returned once!","operationId":"createApiKey","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","scopes"],"properties":{"name":{"type":"string","description":"Friendly name for the API key","example":"Production Integration"},"scopes":{"type":"array","items":{"type":"string"},"description":"Permission scopes","example":["tasks:read","tasks:write","agents:read"]},"expires_at":{"type":"string","format":"date-time","description":"Optional expiration date"},"rate_limit":{"type":"integer","minimum":10,"maximum":10000,"description":"Custom rate limit (requests/minute)"}}}}}},"responses":{"200":{"description":"API key created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true},"key":{"$ref":"#/components/schemas/ApiKey"},"secret":{"type":"string","description":"Full API key secret - only shown once!","example":"dby_k_abc123xyz..."}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API Key authentication. Prefix with \"Bearer \"."}},"schemas":{"Agent":{"type":"object","properties":{"id":{"type":"string","example":"agent_abc123"},"name":{"type":"string","example":"Backend Developer Agent"},"description":{"type":"string","example":"Handles backend development tasks"},"role":{"type":"string","example":"developer"},"status":{"type":"string","enum":["active","draft","archived"],"example":"active"},"requires_approval":{"type":"boolean","example":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Integration":{"type":"object","properties":{"id":{"type":"string","example":"int_abc123"},"type":{"type":"string","enum":["git","task_management","messaging","ai"],"example":"git"},"name":{"type":"string","example":"GitHub"},"provider":{"type":"string","example":"github"},"is_active":{"type":"boolean","example":true},"is_verified":{"type":"boolean","example":true},"stats":{"type":"object","properties":{"tasks_processed":{"type":"integer","example":1542},"last_sync_at":{"type":"string","format":"date-time"}}},"created_at":{"type":"string","format":"date-time"}}},"Approval":{"type":"object","properties":{"id":{"type":"string","example":"approval_abc123"},"task_id":{"type":"string","example":"task_xyz"},"agent_id":{"type":"string","example":"agent_abc123"},"agent_name":{"type":"string","example":"Backend Developer Agent"},"action_type":{"type":"string","example":"pr_merge"},"action_description":{"type":"string","example":"Merge PR #42 to main"},"status":{"type":"string","enum":["pending","approved","rejected","expired"],"example":"pending"},"priority":{"type":"string","enum":["low","medium","high","urgent"],"example":"medium"},"created_at":{"type":"string","format":"date-time"}}},"ApiKey":{"type":"object","properties":{"key_id":{"type":"string","example":"key_abc123"},"name":{"type":"string","example":"Production Integration"},"key_prefix":{"type":"string","example":"sk_live_abc1..."},"scopes":{"type":"array","items":{"type":"string"},"example":["tasks:read","agents:read"]},"is_active":{"type":"boolean","example":true},"rate_limit":{"type":"integer","example":100},"last_used_at":{"type":"string","format":"date-time","nullable":true},"expires_at":{"type":"string","format":"date-time","nullable":true},"created_at":{"type":"string","format":"date-time"}}},"Task":{"type":"object","properties":{"id":{"type":"string","example":"task_abc123"},"title":{"type":"string","example":"Fix authentication bug"},"description":{"type":"string","example":"Users cannot log in after password reset"},"status":{"type":"string","enum":["pending","in_progress","completed","failed"],"example":"in_progress"},"priority":{"type":"string","enum":["low","medium","high"],"example":"medium"},"agent_id":{"type":"string","example":"agent_abc123","nullable":true},"agent_name":{"type":"string","example":"Backend Developer Agent","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ControlVerdict":{"type":"object","description":"Policy verdict for an inline control-point check. The HTTP status mirrors `action`: 200 pass/redact, 202 pause_for_approval, 403 block.","properties":{"action":{"type":"string","enum":["pass","block","redact","pause_for_approval"],"example":"block"},"decision_id":{"type":"string","description":"Pass this to /api/v1/controls/outcome to close the adherence loop","example":"dec_abc123def456"},"correlation_id":{"type":"string","description":"Echo of the request's correlation_id (when provided)"},"reason":{"type":"string","description":"Human-readable explanation of the verdict","example":"Blocked by tenant policy: no external email with PII"}}},"Policy":{"type":"object","properties":{"policy_id":{"type":"string","example":"pol_user_abc123"},"layer":{"type":"integer","enum":[1,2,3,4],"description":"1=Platform, 2=Org, 3=Tenant, 4=Process","example":3},"scope_id":{"type":"string","nullable":true,"description":"null for layer 1; org_id for layer 2; tenant_id for layer 3; workflow_id for layer 4"},"text":{"type":"string","example":"Never send customer PII to external email addresses"},"source":{"type":"string","example":"user_authored"},"framework_ref":{"type":"string","nullable":true},"severity":{"type":"string","enum":["critical","high","medium","low"],"example":"high"},"is_active":{"type":"boolean","example":true},"version":{"type":"integer","example":1},"authored_by":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Pagination":{"type":"object","properties":{"total":{"type":"integer","example":42},"limit":{"type":"integer","example":20},"offset":{"type":"integer","example":0},"has_more":{"type":"boolean","example":true}}},"Error":{"type":"object","properties":{"success":{"type":"boolean","example":false},"error":{"type":"string","example":"Error code"},"message":{"type":"string","example":"Human readable error message"}}}},"responses":{"BadRequest":{"description":"Bad Request - Invalid parameters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":"validation_error","message":"Invalid request body","errors":{"field":["Error message"]}}}}},"Unauthorized":{"description":"Unauthorized - Missing or invalid authentication","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":"unauthorized","message":"Invalid or missing API key"}}}},"Forbidden":{"description":"Forbidden - Missing required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":"forbidden","message":"API key missing required scope: tasks:write"}}}},"NotFound":{"description":"Not Found - Resource does not exist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"success":false,"error":"not_found","message":"Resource not found"}}}},"RateLi

# --- truncated at 32 KB (32 KB total) ---
# Full source: https://artifacts.apis.io/dobby-ai-com/openapi/_original/dobby-ai-com-api-openapi.json