{"openapi":"3.1.0","info":{"title":"Coagentic API","version":"1.0.0","summary":"AI-powered SaaS platform — programmatic access to projects, workflows, agents, and billing.","description":"Coagentic exposes a REST + SSE API for the same functionality available in the dashboard.\n\n**Authentication.** Two options:\n- Cookie session (issued by `POST /auth/sign-in`); used by the web dashboard.\n- API tokens: send `Authorization: Bearer coag_<id>_<secret>`. Create in **Settings → API tokens**.\n\n**Rate limits.** Per-tenant limits are applied on `/agent`, `/files`, `/rows`, `/conversations`, `/projects`, and `/workflow-runs`. The response includes `X-RateLimit-*` headers.\n\nWebhook signing, error envelopes, and pagination conventions are documented in the relevant tags.","contact":{"name":"Coagentic support","email":"support@coagentic.work"},"license":{"name":"Proprietary"},"termsOfService":"https://coagentic.work/terms"},"servers":[{"url":"https://api.coagentic.work","description":"Production"},{"url":"http://localhost:4000","description":"Local development"}],"tags":[{"name":"Auth","description":"Sign in, session, profile"},{"name":"Projects","description":"CRUD over the projects in your workspace"},{"name":"Conversations","description":"Agent chat history"},{"name":"Agent","description":"Real-time agent execution"},{"name":"Databases","description":"Per-project tables and rows"},{"name":"Workflows","description":"Triggers + actions"},{"name":"Integrations","description":"Connected third-party providers"},{"name":"Files","description":"Project file tree"},{"name":"Webhooks","description":"Inbound + outbound webhooks"},{"name":"Forms","description":"Public form submissions"},{"name":"Billing","description":"Polar checkout + portal"},{"name":"API tokens","description":"Bearer tokens for programmatic access"}],"security":[{"cookie":[]},{"bearer":[]}],"components":{"securitySchemes":{"cookie":{"type":"apiKey","in":"cookie","name":"coagentic_session"},"bearer":{"type":"http","scheme":"bearer","bearerFormat":"coag_<id>_<secret>"}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","example":"Unauthorized"},"issues":{"type":"array","items":{"type":"object"}}}},"Project":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["landing","ecommerce","blog","saas","portfolio","custom"]},"status":{"type":"string","enum":["draft","building","deploying","live","error","archived"]},"subdomain":{"type":"string"},"url":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Conversation":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"title":{"type":"string"},"messageCount":{"type":"integer"},"inputTokens":{"type":"integer"},"outputTokens":{"type":"integer"},"costUsd":{"type":"number"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Database":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Column":{"type":"object","required":["name","type"],"properties":{"name":{"type":"string","maxLength":40},"type":{"type":"string","description":"Column type. See `GET /databases` docs for the set."},"nullable":{"type":"boolean","default":true},"unique":{"type":"boolean","default":false},"primary":{"type":"boolean","default":false},"defaultValue":{"type":"string"}}},"Table":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"databaseId":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"},"name":{"type":"string","pattern":"^[a-z_][a-z0-9_]*$"},"columns":{"type":"array","items":{"$ref":"#/components/schemas/Column"}},"access":{"type":"object","description":"Who may read or write this table from outside the dashboard.","properties":{"publicRead":{"type":"boolean"},"publicWrite":{"type":"boolean"},"publicColumns":{"type":"array","items":{"type":"string"}},"assistantReadable":{"type":"boolean"},"assistantWritable":{"type":"boolean"}}},"rowCount":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Row":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tableId":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"},"data":{"type":"object","additionalProperties":true,"description":"The row itself, keyed by column name."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"File":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"},"path":{"type":"string","example":"index.html"},"contentType":{"type":"string"},"binary":{"type":"boolean"},"size":{"type":"integer"},"seo":{"$ref":"#/components/schemas/FileSeo"},"content":{"type":"string","description":"Text files only, and only on GET /files/{id}."},"contentBase64":{"type":"string","description":"Binary files only, and only on GET /files/{id}."},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"FileSeo":{"type":"object","description":"What search engines and link previews see for a page.","properties":{"title":{"type":"string","maxLength":120},"description":{"type":"string","maxLength":300},"ogImage":{"type":"string","maxLength":400},"noIndex":{"type":"boolean"}}},"Workflow":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"trigger":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["webhook","form_submit","cron","db_change","analytics_threshold","inbound_email"]},"config":{"type":"object","additionalProperties":true}}},"actions":{"type":"array","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string"},"config":{"type":"object","additionalProperties":true}}}},"nodes":{"type":"array","items":{"type":"object","additionalProperties":true},"description":"Graph form. A branching workflow has nodes + edges; a linear one may use `actions` alone."},"edges":{"type":"array","items":{"type":"object","additionalProperties":true}},"enabled":{"type":"boolean"},"webhookSecret":{"type":"string","description":"Present for webhook-triggered workflows. Sign the raw body with it — see POST /webhooks/{workflowId}."},"lastRunAt":{"type":"string","format":"date-time"}}},"Integration":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"projectId":{"type":"string","format":"uuid"},"provider":{"type":"string"},"name":{"type":"string"},"credentials":{"type":"object","additionalProperties":{"type":"string"},"description":"Always masked on the way out — every value reads as bullets."},"config":{"type":"object","additionalProperties":true},"enabled":{"type":"boolean"}}},"ChatMessage":{"type":"object","required":["role","content"],"properties":{"role":{"type":"string","enum":["user","assistant"]},"content":{"type":"string"}}}},"responses":{"Unauthorized":{"description":"Missing or invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFound":{"description":"Resource does not exist or is not visible to the caller","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimited":{"description":"Rate limit exceeded","headers":{"Retry-After":{"schema":{"type":"integer"},"description":"Seconds to wait before retrying"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"paths":{"/health":{"get":{"tags":["Auth"],"summary":"Liveness probe","security":[],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/auth/sign-in":{"post":{"tags":["Auth"],"summary":"Sign in with email + password","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"},"totpCode":{"type":"string","description":"Required when 2FA is enabled"}}}}}},"responses":{"200":{"description":"Session established (cookie set)"},"401":{"$ref":"#/components/responses/Unauthorized"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/auth/me":{"get":{"tags":["Auth"],"summary":"Current user + tenant","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/projects":{"get":{"tags":["Projects"],"summary":"List projects in the workspace","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Projects"],"summary":"Create a project","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["landing","ecommerce","blog","saas","portfolio","custom"]}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/Project"}}}}}}}}},"/projects/{id}":{"get":{"tags":["Projects"],"summary":"Get a single project","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Projects"],"summary":"Update a project","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Updated"}}},"delete":{"tags":["Projects"],"summary":"Delete a project","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Deleted"}}}},"/conversations":{"get":{"tags":["Conversations"],"summary":"List conversations","responses":{"200":{"description":"OK"}}},"post":{"tags":["Conversations"],"summary":"Create an empty conversation","responses":{"201":{"description":"Created"}}}},"/agent/chat":{"post":{"tags":["Agent"],"summary":"Stream a turn of agent chat (SSE)","description":"Streams `delta`, `tool_call_start`, `tool_call_done`, `usage`, `done`, `error` events as Server-Sent Events. The first event always carries the `conversationId` so a fresh conversation can be persisted client-side.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["messages"],"properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"},"minItems":1},"conversationId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"SSE stream","content":{"text/event-stream":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/api-tokens":{"get":{"tags":["API tokens"],"summary":"List API tokens for the workspace","responses":{"200":{"description":"OK"}}},"post":{"tags":["API tokens"],"summary":"Create a new API token (plaintext returned once)","responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"plain":{"type":"string","description":"Show this to the user once; not retrievable later."},"preview":{"type":"string"}}}}}}}}},"/billing/checkout":{"post":{"tags":["Billing"],"summary":"Create a hosted checkout session for a tier","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["tier"],"properties":{"tier":{"type":"string","enum":["starter","pro","business"]},"cadence":{"type":"string","enum":["monthly","annual"]}}}}}},"responses":{"200":{"description":"Hosted checkout URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}}}}},"/databases":{"get":{"tags":["Databases"],"summary":"List databases in the workspace","parameters":[{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Narrow to one project."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"databases":{"type":"array","items":{"$ref":"#/components/schemas/Database"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Databases"],"summary":"Create a database for a project","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId"],"properties":{"projectId":{"type":"string","format":"uuid"},"name":{"type":"string","default":"main","maxLength":60}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"database":{"$ref":"#/components/schemas/Database"}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"A database already exists for that project","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/databases/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Databases"],"summary":"Get one database","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"database":{"$ref":"#/components/schemas/Database"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Databases"],"summary":"Delete a database and every table in it","responses":{"200":{"description":"Deleted"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/databases/{id}/tables":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Database id."}],"get":{"tags":["Databases"],"summary":"List the tables in a database","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"tables":{"type":"array","items":{"$ref":"#/components/schemas/Table"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Databases"],"summary":"Create a table","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","columns"],"properties":{"name":{"type":"string","pattern":"^[a-z_][a-z0-9_]*$"},"columns":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/Column"}}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"table":{"$ref":"#/components/schemas/Table"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/tables/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Databases"],"summary":"Rename a table, change its columns, or change who may read it","description":"Every field is optional; send only what changes. Removing a column drops its data.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"columns":{"type":"array","items":{"$ref":"#/components/schemas/Column"}},"access":{"type":"object","properties":{"publicRead":{"type":"boolean"},"publicWrite":{"type":"boolean"},"publicColumns":{"type":"array","items":{"type":"string"}},"assistantReadable":{"type":"boolean"},"assistantWritable":{"type":"boolean"}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"table":{"$ref":"#/components/schemas/Table"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Databases"],"summary":"Delete a table and its rows","responses":{"200":{"description":"Deleted"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/rows":{"get":{"tags":["Databases"],"summary":"List rows in a table","parameters":[{"name":"tableId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"rows":{"type":"array","items":{"$ref":"#/components/schemas/Row"}}}}}}},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Databases"],"summary":"Insert a row","parameters":[{"name":"tableId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","additionalProperties":true}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"row":{"$ref":"#/components/schemas/Row"}}}}}},"400":{"description":"The row does not match the table's columns","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/rows/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Databases"],"summary":"Update a row","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["data"],"properties":{"data":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"row":{"$ref":"#/components/schemas/Row"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Databases"],"summary":"Delete a row","responses":{"200":{"description":"Deleted"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/rows/export":{"get":{"tags":["Databases"],"summary":"Export a table as CSV","parameters":[{"name":"tableId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"CSV","content":{"text/csv":{"schema":{"type":"string"}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/rows/import":{"post":{"tags":["Databases"],"summary":"Import rows from CSV","parameters":[{"name":"tableId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"text/csv":{"schema":{"type":"string"}}}},"responses":{"200":{"description":"How many rows landed, and what was skipped","content":{"application/json":{"schema":{"type":"object","properties":{"inserted":{"type":"integer"},"skipped":{"type":"integer"},"errors":{"type":"array","items":{"type":"string"}}}}}}}}}},"/files":{"get":{"tags":["Files"],"summary":"List a project's files","description":"Metadata only — read one file to get its content.","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/File"}}}}}}},"400":{"description":"projectId is required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}},"post":{"tags":["Files"],"summary":"Write a text file","description":"Creates the file, or replaces it when the path already exists. Binary files go through /files/upload.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","path","content"],"properties":{"projectId":{"type":"string","format":"uuid"},"path":{"type":"string","example":"index.html"},"content":{"type":"string"},"contentType":{"type":"string"}}}}}},"responses":{"201":{"description":"Written","content":{"application/json":{"schema":{"type":"object","properties":{"file":{"$ref":"#/components/schemas/File"}}}}}},"403":{"description":"The project is read-only — the workspace is over its plan's allowance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/files/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Files"],"summary":"Read one file, with its content","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"file":{"$ref":"#/components/schemas/File"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Files"],"summary":"Delete a file","responses":{"200":{"description":"Deleted"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/files/{id}/rename":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Files"],"summary":"Move a file to another path","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["path"],"properties":{"path":{"type":"string","maxLength":200}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"file":{"$ref":"#/components/schemas/File"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/files/{id}/seo":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"patch":{"tags":["Files"],"summary":"Set what search engines and link previews see for a page","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileSeo"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"file":{"$ref":"#/components/schemas/File"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/files/upload":{"post":{"tags":["Files"],"summary":"Upload a binary file","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"path":{"type":"string"}}}}}},"responses":{"201":{"description":"Uploaded","content":{"application/json":{"schema":{"type":"object","properties":{"file":{"$ref":"#/components/schemas/File"}}}}}},"400":{"description":"Rejected — too large, or an SVG carrying script content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/workflows":{"get":{"tags":["Workflows"],"summary":"List workflows","parameters":[{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workflows":{"type":"array","items":{"$ref":"#/components/schemas/Workflow"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Workflows"],"summary":"Create a workflow","description":"A linear workflow is a trigger plus `actions`. A branching one sends `nodes` + `edges` instead; both open and run identically.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","name","trigger"],"properties":{"projectId":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"trigger":{"type":"object"},"actions":{"type":"array","items":{"type":"object"}},"nodes":{"type":"array","items":{"type":"object"}},"edges":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"workflow":{"$ref":"#/components/schemas/Workflow"}}}}}}}}},"/workflows/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Workflows"],"summary":"Get one workflow","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workflow":{"$ref":"#/components/schemas/Workflow"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Workflows"],"summary":"Update a workflow, or turn it on and off","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"trigger":{"type":"object"},"actions":{"type":"array","items":{"type":"object"}},"nodes":{"type":"array","items":{"type":"object"}},"edges":{"type":"array","items":{"type":"object"}},"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workflow":{"$ref":"#/components/schemas/Workflow"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Workflows"],"summary":"Delete a workflow","responses":{"200":{"description":"Deleted"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/workflows/{id}/rotate-secret":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Workflows"],"summary":"Mint a new webhook signing secret","description":"The old secret stops working immediately. Anything already signing calls to this workflow must be updated.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workflow":{"$ref":"#/components/schemas/Workflow"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/workflow-runs":{"get":{"tags":["Workflows"],"summary":"List recent runs","parameters":[{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"workflowId","in":"query","schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"runs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"workflowId":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["success","error","running"]},"results":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string"},"ok":{"type":"boolean"},"message":{"type":"string"}}}},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/workflow-runs/{workflowId}/run":{"parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Workflows"],"summary":"Run a workflow now","description":"Runs it exactly as its trigger would, with the payload you supply.","requestBody":{"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"The run, and what each action did","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"results":{"type":"array","items":{"type":"object"}},"error":{"type":"string"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/integrations":{"get":{"tags":["Integrations"],"summary":"List connected providers","description":"Credentials come back masked — this endpoint can never read a secret back out.","parameters":[{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"integrations":{"type":"array","items":{"$ref":"#/components/schemas/Integration"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Integrations"],"summary":"Connect a provider","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","provider","credentials"],"properties":{"projectId":{"type":"string","format":"uuid"},"provider":{"type":"string"},"name":{"type":"string"},"credentials":{"type":"object","additionalProperties":{"type":"string"},"description":"Stored encrypted; never read back."},"config":{"type":"object","additionalProperties":true}}}}}},"responses":{"201":{"description":"Connected","content":{"application/json":{"schema":{"type":"object","properties":{"integration":{"$ref":"#/components/schemas/Integration"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/integrations/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Integrations"],"summary":"Get one integration","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"integration":{"$ref":"#/components/schemas/Integration"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Integrations"],"summary":"Update credentials, config, or turn it off","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"credentials":{"type":"object","additionalProperties":{"type":"string"}},"config":{"type":"object","additionalProperties":true},"enabled":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"integration":{"$ref":"#/components/schemas/Integration"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Integrations"],"summary":"Disconnect a provider","responses":{"200":{"description":"Disconnected"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/integrations/{id}/test":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"tags":["Integrations"],"summary":"Check the credentials still work","responses":{"200":{"description":"What the provider answered","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"message":{"type":"string"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/forms/{subdomain}":{"parameters":[{"name":"subdomain","in":"path","required":true,"schema":{"type":"string"},"description":"The project's subdomain — the site the form is on."}],"post":{"tags":["Forms"],"summary":"Submit a form from a live site","security":[],"description":"Public and CORS-open, so a form on the customer's own page can post here directly. The site must be live. Bodies are capped at 256 KB and the endpoint is rate limited per IP.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Recorded"},"404":{"description":"No live site at that subdomain","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Submission too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/webhooks/{workflowId}":{"post":{"tags":["Webhooks"],"summary":"Trigger a workflow over HTTP","security":[],"parameters":[{"name":"workflowId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"description":"Public endpoint. If the workflow has a `webhookSecret`, the caller must include `X-Coagentic-Signature` (HMAC-SHA256 of the raw body, hex).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Workflow accepted"}}}}}}