# Pyromanic API > Everything the Pyromanic app can do, available over HTTP. Authenticate with a secret key as a bearer token. Breaking changes are announced by date-pinned version; send `Pyromanic-Version` to pin one. Base URL: https://api.pyromanic.com Version: 2026-08-11 Machine-readable spec: https://api.pyromanic.com/openapi.json MCP endpoint: https://api.pyromanic.com/mcp (same key, same scopes; tools named pyromanic_) ## Authentication Send a secret key as a bearer token: `Authorization: Bearer sk_live_...` A key is scoped to one company. A company id in a path is checked against the key, never trusted over it. Publishable keys (pk_live_) are refused here — they are for the public delivery API only. ## Errors All failures: {"errors":[{"code":"...","message":"..."}]} Codes: bad_request(400) unauthorised(401) not_found(404) method_not_allowed(405) rate_limited(429) internal(500). Branch on code, never on message. ## Endpoints ### Companies - GET /v1/companies List the companies this key can act on. A key is scoped to a single company, so this returns exactly one. Use it to discover the id for every other endpoint rather than hard-coding one. scope: company:read - GET /v1/companies/{companyId} Fetch a company. The company your key is scoped to. Any other id returns 404. scope: company:read - PATCH /v1/companies/{companyId} Update a company. scope: company:write ### Plan - GET /v1/companies/{companyId}/plan/boards List roadmap boards. scope: plan:read - GET /v1/companies/{companyId}/plan/boards/{boardId} Fetch one roadmap board. scope: plan:read - GET /v1/companies/{companyId}/plan/boards/{boardId}/items List items on a board. Includes drafts. This is the authoring view, not what visitors see. scope: plan:read - POST /v1/companies/{companyId}/plan/boards/{boardId}/items Add an item to a board. Created as a draft unless a status is given. Nothing becomes visible until you publish. scope: plan:write - GET /v1/companies/{companyId}/plan/items/{itemId} Fetch one item. scope: plan:read - PATCH /v1/companies/{companyId}/plan/items/{itemId} Update an item. Slug is deliberately not updatable — changing it breaks every link already shared. scope: plan:write - DELETE /v1/companies/{companyId}/plan/items/{itemId} Delete an item. Removes the authoring record. Anything already published stays visible until the next publish. scope: plan:write - POST /v1/companies/{companyId}/plan/boards/{boardId}/publish/preview See exactly what publishing would make visible. A dry run. Nothing changes. Worth calling first from automation, since publishing is the point at which drafts become public and there is no undo beyond republishing. scope: plan:read - POST /v1/companies/{companyId}/plan/boards/{boardId}/publish Publish the board. Makes published items visible to the delivery API. Call the preview first — this is the moment drafts become public. scope: plan:publish ### Feedback - GET /v1/companies/{companyId}/feedback List reviews and mentions. scope: feedback:read - GET /v1/companies/{companyId}/feedback/{feedbackId} Fetch one review or mention. scope: feedback:read - PATCH /v1/companies/{companyId}/feedback/{feedbackId}/reply Write or update the reply to a review. Stores the reply text and its workflow status. This does not send anything — posting back to the platform is a separate, human-confirmed step, and several sources are read-only. Set status to "approved" to mark a reply ready to send. scope: feedback:write ### Metrics - GET /v1/companies/{companyId}/metrics/definitions List metric definitions. What this company measures. Read this to learn the keys the points endpoint accepts. scope: metrics:read - GET /v1/companies/{companyId}/metrics/points Read a metric series. Values for one metric over a date range. Points are keyed so a re-send overwrites in place, which is why a backfill and a nightly recompute both look like this. scope: metrics:read ### Optimise - GET /v1/companies/{companyId}/optimise/sites List measured sites. scope: optimise:read - GET /v1/companies/{companyId}/optimise/sites/{siteId}/goals List goals defined on a site. scope: optimise:read - GET /v1/companies/{companyId}/optimise/audits List site audits. Scores and summaries. Fetch one audit for its per-page findings. scope: optimise:read - GET /v1/companies/{companyId}/optimise/audits/{auditId} Fetch one audit, with findings. scope: optimise:read ### Broadcast - GET /v1/companies/{companyId}/broadcast/plans List content plans. scope: broadcast:read - GET /v1/companies/{companyId}/broadcast/ideas List content ideas. scope: broadcast:read - GET /v1/companies/{companyId}/broadcast/posts List posts. Drafts, scheduled and published. Filter by status to get a queue. scope: broadcast:read - POST /v1/companies/{companyId}/broadcast/posts Draft a post. Created as a draft. Set scheduledFor and status to "scheduled" to queue it — the dispatcher picks it up from there. Nothing here sends anything itself. scope: broadcast:write - GET /v1/companies/{companyId}/broadcast/posts/{postId} Fetch one post. scope: broadcast:read - PATCH /v1/companies/{companyId}/broadcast/posts/{postId} Update or schedule a post. Only unsent posts can be edited. scope: broadcast:write - DELETE /v1/companies/{companyId}/broadcast/posts/{postId} Delete an unsent post. scope: broadcast:write - GET /v1/companies/{companyId}/broadcast/channels List connected channels. Which platforms are connected and whether their credentials still work. scope: broadcast:read ### Context - GET /v1/companies/{companyId}/context/brand-kit Fetch the brand kit. Voice, colours and art direction. Read this before generating anything. scope: context:read - PATCH /v1/companies/{companyId}/context/brand-kit Update the brand kit. Creates it if the company has none. Changing voice guidelines changes every future draft. scope: context:write - GET /v1/companies/{companyId}/context/content-types List content types. The kinds of post this company publishes, and how each should be written. scope: context:read - POST /v1/companies/{companyId}/context/content-types Add a content type. scope: context:write - PATCH /v1/companies/{companyId}/context/content-types/{contentTypeId} Update a content type. scope: context:write - GET /v1/companies/{companyId}/context/goals List brand goals. scope: context:read