{"openapi":"3.1.0","info":{"title":"Cadencz API","description":"Cadencz Phase 0 API. Frontend developers can use this Swagger page as the live request/response contract. Click `Authorize` and paste a Supabase access token for user-scoped endpoints.","version":"0.1.0"},"paths":{"/mcp":{"get":{"tags":["mcp"],"summary":"Mcp Get","operationId":"mcp_get_mcp_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["mcp"],"summary":"Mcp Endpoint","operationId":"mcp_endpoint_mcp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/health":{"get":{"tags":["health"],"summary":"API health check","operationId":"health_api_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/api/v1/config":{"get":{"tags":["config"],"summary":"Public application configuration","description":"The customer-safe slice of the live configuration: which channels are on, which features are available, and the display limits. Unauthenticated so the marketing site and the sign-in shell can read it too.","operationId":"public_config_api_v1_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Public Config Api V1 Config Get"}}}}}}},"/api/v1/admin/config":{"get":{"tags":["admin"],"summary":"Get the live application configuration","description":"Returns the effective configuration, the shipped defaults to compare it against, and the field schema the admin UI renders from.","operationId":"get_config_api_v1_admin_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConfigResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"put":{"tags":["admin"],"summary":"Save the application configuration","description":"Validates and persists a new configuration, records the change set for audit, and publishes it to every worker. Requires `confirm: true` and the `expected_version` returned by GET /admin/config.","operationId":"put_config_api_v1_admin_config_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConfigSaveRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConfigResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/admin/config/preview":{"post":{"tags":["admin"],"summary":"Check a configuration without saving it","description":"Returns the exact change set a save would apply, plus any validation errors and non-blocking warnings. This is what the confirmation dialog shows, so the admin approves the real diff rather than a guess at it.","operationId":"preview_config_api_v1_admin_config_preview_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConfigSaveRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConfigPreviewResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/admin/config/reset":{"post":{"tags":["admin"],"summary":"Reset configuration to the shipped defaults","description":"Resets one section, or everything when no section is given.","operationId":"reset_config_api_v1_admin_config_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConfigResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminConfigResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/admin/config/history":{"get":{"tags":["admin"],"summary":"List configuration changes","description":"Newest first. Every save records who changed what, and from what to what.","operationId":"config_history_api_v1_admin_config_history_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminConfigAuditEntry"},"title":"Response Config History Api V1 Admin Config History Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/admin/overview":{"get":{"tags":["admin"],"summary":"App-wide usage, revenue and margin","description":"Admin-only summary: accounts, subscriptions, credit and model spend, the per-plan margin model, and how each channel is actually being used.","operationId":"overview_api_v1_admin_overview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOverviewResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/admin/users":{"get":{"tags":["admin"],"summary":"List accounts","description":"Read-only. Admin access is granted by setting `users.is_admin` in the database; there is deliberately no endpoint that promotes a user.","operationId":"list_users_api_v1_admin_users_get","parameters":[{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Search"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AdminUserRow"},"title":"Response List Users Api V1 Admin Users Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/admin/provision":{"post":{"tags":["admin"],"summary":"Grant credits or activate a plan without Dodo","description":"Development and recovery tool. Activates a plan tier and/or grants credits for a workspace without going through Dodo Payments — use it when the webhook cannot reach a dev machine. It creates no real payment.","operationId":"provision_api_v1_admin_provision_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminProvisionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/waitlist":{"post":{"tags":["waitlist"],"summary":"Join the Cadencz waitlist","description":"Stores a normalized email once. Repeated submissions are safe and return joined=false.","operationId":"join_waitlist_api_v1_waitlist_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistJoinRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistJoinResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/waitlist/access":{"get":{"tags":["waitlist"],"summary":"Check whether the signed-in user has early access","operationId":"check_waitlist_access_api_v1_waitlist_access_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WaitlistAccessResponse"}}}}}}},"/api/v1/agents/run":{"post":{"tags":["agents"],"summary":"Run the agent graph","description":"Executes the Cadencz agent graph for one request and returns the run with its full per-agent trace. Phase A route is 'answer' (a strict one-line assistant).","operationId":"run_agents_api_v1_agents_run_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRunRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRunRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/agents/runs":{"get":{"tags":["agents"],"summary":"List recent agent runs + traces","operationId":"list_agent_runs_api_v1_agents_runs_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AgentRunRead"},"title":"Response List Agent Runs Api V1 Agents Runs Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/agents/runs/{run_id}":{"get":{"tags":["agents"],"summary":"Get an agent run + trace","operationId":"get_agent_run_api_v1_agents_runs__run_id__get","parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentRunRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/media":{"get":{"tags":["media"],"summary":"List media assets","operationId":"list_media_api_v1_media_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Media Api V1 Media Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"post":{"tags":["media"],"summary":"Upload an image","description":"Stores the file in the media bucket and records a MediaAsset. JPEG, PNG, GIF or WebP, 10MB max. WebP and still GIFs are stored as PNG; animated GIFs are kept and marked `gif`.","operationId":"upload_media_api_v1_media_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_media_api_v1_media_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Upload Media Api V1 Media Post"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"413":{"description":"File too large."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/media/{asset_id}":{"patch":{"tags":["media"],"summary":"Update a media asset's alt text","operationId":"update_media_api_v1_media__asset_id__patch","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AltTextUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Media Api V1 Media  Asset Id  Patch"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"delete":{"tags":["media"],"summary":"Delete a media asset","operationId":"delete_media_api_v1_media__asset_id__delete","parameters":[{"name":"asset_id","in":"path","required":true,"schema":{"type":"string","title":"Asset Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/strategy":{"get":{"tags":["strategy"],"summary":"Get the workspace agent strategy","operationId":"get_strategy_api_v1_strategy_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StrategyRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"put":{"tags":["strategy"],"summary":"Update the workspace agent strategy","operationId":"put_strategy_api_v1_strategy_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StrategyUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StrategyRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/strategy/learn":{"post":{"tags":["strategy"],"summary":"Learn the workspace voice from past posts","description":"Runs the smart-tier voice agent over 5-10 past posts, extracts a tone profile, and stores it on the strategy so every future draft is written in the user's voice.","operationId":"learn_voice_api_v1_strategy_learn_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LearnVoiceRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LearnVoiceResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/plans/generate":{"post":{"tags":["plans"],"summary":"Generate the week's content plan","description":"Runs the smart-tier planner over the workspace strategy, learned voice, and a summary of recent analytics (the results→plan loop), and returns a themed week — each item with a why.","operationId":"generate_plan_api_v1_plans_generate_post","requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PlanGenerateRequest"},{"type":"null"}],"title":" Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/plans/current":{"get":{"tags":["plans"],"summary":"Get the current content plan","operationId":"current_plan_api_v1_plans_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/plans/stack":{"get":{"tags":["plans"],"summary":"Every planned post still waiting on a verdict, across weeks","operationId":"plan_stack_api_v1_plans_stack_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanStackRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/plans/items/{item_id}":{"patch":{"tags":["plans"],"summary":"Edit a plan item (theme, prompt, platforms, time)","operationId":"update_plan_item_route_api_v1_plans_items__item_id__patch","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanItemUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanItemRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"delete":{"tags":["plans"],"summary":"Dismiss (remove) a plan item","operationId":"dismiss_plan_item_route_api_v1_plans_items__item_id__delete","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/plans/items/{item_id}/refine":{"post":{"tags":["plans"],"summary":"Refine a planned post from user feedback","operationId":"refine_plan_item_route_api_v1_plans_items__item_id__refine_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanItemRefineRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanItemRefineResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/plans/items/{item_id}/render":{"post":{"tags":["plans"],"summary":"Retry writing a failed draft","description":"Puts a failed plan item back into `rendering` and re-runs the writer in the background — along with any sibling drafts that failed in the same run. The client polls GET /plans/current and watches items leave `rendering`.","operationId":"retry_render_item_route_api_v1_plans_items__item_id__render_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanItemRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/plans/items/{item_id}/approve":{"post":{"tags":["plans"],"summary":"Approve a plan item into a post","operationId":"approve_plan_item_api_v1_plans_items__item_id__approve_post","parameters":[{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/PlanItemApproveRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveItemResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me":{"get":{"tags":["me"],"summary":"Get the current user and workspace","description":"Validates the Supabase access token, creates the Phase 0 user/workspace record on first sign-in, and returns the active workspace context.","operationId":"current_user_api_v1_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CurrentUserResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Database or auth infrastructure unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/workspace":{"put":{"tags":["me"],"summary":"Remember the workspace this person is working in","description":"The server half of switching: the header decides per request, this row\ndecides where a brand-new device lands.","operationId":"switch_workspace_api_v1_me_workspace_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceSwitchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Switch Workspace Api V1 Me Workspace Put"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/workspaces":{"get":{"tags":["me"],"summary":"Every workspace on this account, and what is in them","description":"Readable by a scheduler too: they can see which rooms they are in, they\njust cannot add, rename, or delete one.","operationId":"list_workspaces_api_v1_me_workspaces_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"post":{"tags":["me"],"summary":"Create another workspace on this account","description":"A second brand on a Business plan. Same account, same pool, new room.\n\nNo subscription row is created: the plan is the account's, and every\nworkspace on it draws from the one pool. A second Free subscription here\nwould quietly double the allowance.","operationId":"create_workspace_api_v1_me_workspaces_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceCreateRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceDetail"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/workspaces/{workspace_id}":{"patch":{"tags":["me"],"summary":"Rename a workspace","operationId":"update_workspace_api_v1_me_workspaces__workspace_id__patch","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceDetail"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"delete":{"tags":["me"],"summary":"Delete a workspace and everything inside it","description":"Permanently deletes the workspace's channels, brains, posts, plans and schedules. Billing records move to a surviving workspace — the plan belongs to the account, not to any one room. Requires the workspace's exact name as `confirm`, and refuses the account's last workspace.","operationId":"remove_workspace_api_v1_me_workspaces__workspace_id__delete","parameters":[{"name":"workspace_id","in":"path","required":true,"schema":{"type":"string","title":"Workspace Id"}},{"name":"confirm","in":"query","required":true,"schema":{"type":"string","description":"The workspace's exact name, typed back. Guards the API the same way the dialog guards the UI.","title":"Confirm"},"description":"The workspace's exact name, typed back. Guards the API the same way the dialog guards the UI."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Remove Workspace Api V1 Me Workspaces  Workspace Id  Delete"}}}},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Bad Request"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/members":{"get":{"tags":["me"],"summary":"Who is on this account, and who is invited","operationId":"list_members_api_v1_me_members_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountMembersResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/members/invites":{"post":{"tags":["me"],"summary":"Invite someone onto this account","operationId":"invite_member_api_v1_me_members_invites_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteCreateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInviteRead"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/members/grants":{"get":{"tags":["me"],"summary":"The capabilities an owner can hand to a member","description":"Named here rather than hardcoded in the client, so adding a grant is one backend change. Money and account structure are deliberately absent: those are what it means to *be* the account, not to help run it, and nothing revocable should be able to end the subscription.","operationId":"list_grants_api_v1_me_members_grants_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AccountGrantRead"},"type":"array","title":"Response List Grants Api V1 Me Members Grants Get"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/members/{membership_id}":{"patch":{"tags":["me"],"summary":"Change what a member is allowed to do","operationId":"update_member_api_v1_me_members__membership_id__patch","parameters":[{"name":"membership_id","in":"path","required":true,"schema":{"type":"string","title":"Membership Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountMemberRead"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"delete":{"tags":["me"],"summary":"Remove a member from this account","operationId":"remove_member_api_v1_me_members__membership_id__delete","parameters":[{"name":"membership_id","in":"path","required":true,"schema":{"type":"string","title":"Membership Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Remove Member Api V1 Me Members  Membership Id  Delete"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/members/invites/{invite_id}/resend":{"post":{"tags":["me"],"summary":"Mail a pending invite again, on a fresh link","description":"Rotates the token and re-sends the email. The previous link stops working immediately, which is also how an invite forwarded to the wrong person is defused.","operationId":"resend_member_invite_api_v1_me_members_invites__invite_id__resend_post","parameters":[{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","title":"Invite Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountInviteRead"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/members/invites/{invite_id}":{"delete":{"tags":["me"],"summary":"Revoke a pending invite","operationId":"revoke_member_invite_api_v1_me_members_invites__invite_id__delete","parameters":[{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","title":"Invite Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Member Invite Api V1 Me Members Invites  Invite Id  Delete"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/invites/pending":{"get":{"tags":["me"],"summary":"Invites waiting for the signed-in person","description":"Resolved from the verified email on the token — no invite link needed. The emailed link was only ever a courier for the address; signing in proves the same thing, so the app can simply ask.","operationId":"list_pending_invites_api_v1_me_invites_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PendingInviteRead"},"type":"array","title":"Response List Pending Invites Api V1 Me Invites Pending Get"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/invites/pending/{invite_id}/accept":{"post":{"tags":["me"],"summary":"Accept an invite the app offered","description":"Same checks as accepting by link — verified address, not revoked, not expired, seat cap under the account lock. The id is not a credential: one that is not addressed to you answers 404.","operationId":"accept_pending_invite_api_v1_me_invites_pending__invite_id__accept_post","parameters":[{"name":"invite_id","in":"path","required":true,"schema":{"type":"string","title":"Invite Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteAcceptResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/invites/{token}":{"get":{"tags":["me"],"summary":"What this invite is, before signing in","description":"Deliberately unauthenticated: the landing page has to be able to say who invited you and to which address *before* it can ask you to sign in, or a wrong-account sign-in is indistinguishable from a dead link. The token is the credential and the address comes back masked.","operationId":"read_invite_api_v1_me_invites__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvitePreviewResponse"}}}},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/me/invites/{token}/accept":{"post":{"tags":["me"],"summary":"Accept a seat invite","operationId":"accept_member_invite_api_v1_me_invites__token__accept_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteAcceptResponse"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Forbidden"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Conflict"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/preferences":{"get":{"tags":["me"],"summary":"Get current user preferences","operationId":"get_preferences_api_v1_me_preferences_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferences"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Database unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"patch":{"tags":["me"],"summary":"Update current user preferences","operationId":"update_preferences_api_v1_me_preferences_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferencesUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferences"}}}},"400":{"description":"Invalid preference value.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Database unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/mcp-tokens":{"get":{"tags":["me"],"summary":"The MCP tokens minted for this workspace","operationId":"list_mcp_tokens_api_v1_me_mcp_tokens_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Mcp Tokens Api V1 Me Mcp Tokens Get"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"post":{"tags":["me"],"summary":"Mint an MCP token","description":"The raw token appears exactly once, here. The auth layer re-checks\n`mcp_enabled` per request too, so this friendly gate is UX, not security.","operationId":"create_mcp_token_api_v1_me_mcp_tokens_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Create Mcp Token Api V1 Me Mcp Tokens Post"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"402":{"description":"Payment Required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/me/mcp-tokens/{token_id}":{"delete":{"tags":["me"],"summary":"Revoke an MCP token","operationId":"revoke_mcp_token_api_v1_me_mcp_tokens__token_id__delete","parameters":[{"name":"token_id","in":"path","required":true,"schema":{"type":"string","title":"Token Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Mcp Token Api V1 Me Mcp Tokens  Token Id  Delete"}}}},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Unauthorized"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}},"description":"Not Found"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/bootstrap":{"get":{"tags":["bootstrap"],"summary":"Everything the app shell needs, in one request","description":"Returns the payloads of `/me`, `/me/preferences`, `/channels`, `/billing/subscription`, `/billing/usage`, `/strategy`, `/plans/current`, `/brains` and `/media` in a single response, each byte-identical to what its own endpoint returns.\n\nOnly `me` is required: it gates the shell, so if it fails the request fails. Every other section degrades to `null` with its name listed in `failed`, which the client should read as *fetch this one yourself*. A `null` section absent from `failed` is a genuine empty — today only `plan`, when the workspace has not generated one yet.","operationId":"bootstrap_api_v1_bootstrap_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BootstrapResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/bootstrap/critical":{"get":{"tags":["bootstrap"],"summary":"Load only the data that gates the authenticated shell","operationId":"critical_bootstrap_api_v1_bootstrap_critical_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CriticalBootstrapResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/bootstrap/deferred":{"get":{"tags":["bootstrap"],"summary":"Warm non-critical workspace data after the shell renders","operationId":"deferred_bootstrap_api_v1_bootstrap_deferred_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeferredBootstrapResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/onboarding/start":{"post":{"tags":["onboarding"],"summary":"Start onboarding from a website or a written brief","operationId":"start_onboarding_api_v1_onboarding_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingStartRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingRunRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/onboarding/current":{"get":{"tags":["onboarding"],"summary":"Poll the latest onboarding run","operationId":"current_onboarding_api_v1_onboarding_current_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingRunRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/onboarding/cancel":{"post":{"tags":["onboarding"],"summary":"Stop the running onboarding run","description":"Stop setup and hand the workspace back.\n\nDeliberately not a 409 when the run has already finished: the button exists\nbecause a run looked stuck, and telling someone their stop failed because\nthe thing stopped on its own is a worse answer than the run itself.","operationId":"cancel_onboarding_api_v1_onboarding_cancel_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingRunRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/onboarding/retry":{"post":{"tags":["onboarding"],"summary":"Retry a failed onboarding run","operationId":"retry_onboarding_api_v1_onboarding_retry_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingRunRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/company/profile":{"get":{"tags":["company"],"summary":"Get the company profile","operationId":"get_company_profile_api_v1_company_profile_get","parameters":[{"name":"brain_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyProfileRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"put":{"tags":["company"],"summary":"Replace the structured company profile","operationId":"update_company_profile_api_v1_company_profile_put","parameters":[{"name":"brain_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyProfileUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyProfileRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/company/documents/{slug}":{"patch":{"tags":["company"],"summary":"Update one plain-text company document","operationId":"update_company_document_api_v1_company_documents__slug__patch","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}},{"name":"brain_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDocumentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyDocumentRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels":{"get":{"tags":["channels"],"summary":"List connected channels","description":"Returns the publishing channels connected to the current user's workspace.","operationId":"list_channels_api_v1_channels_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ChannelRead"},"type":"array","title":"Response List Channels Api V1 Channels Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/bluesky":{"post":{"tags":["channels"],"summary":"Connect a Bluesky account","description":"Authenticates a Bluesky handle with an app password and stores encrypted publishing credentials for the current workspace.","operationId":"connect_bluesky_api_v1_channels_connect_bluesky_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlueskyConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/slack":{"post":{"tags":["channels"],"summary":"Connect a Slack channel","description":"Verifies a Slack Incoming Webhook by posting a confirmation message, then stores the webhook URL encrypted for the workspace.","operationId":"connect_slack_api_v1_channels_connect_slack_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SlackConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/devto":{"post":{"tags":["channels"],"summary":"Connect a dev.to account","description":"Validates a dev.to API key and stores it encrypted. dev.to rather than Medium because Medium stopped issuing API tokens to new integrations in January 2025 — there is no way to onboard a new user there.","operationId":"connect_devto_api_v1_channels_connect_devto_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DevToConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/wordpress":{"post":{"tags":["channels"],"summary":"Connect a WordPress site","description":"Validates a site URL plus an application password and stores the credential encrypted. Application passwords are issued by WordPress core under Users → Profile and are revocable on their own, so there is no OAuth app to register and no review to wait on.","operationId":"connect_wordpress_api_v1_channels_connect_wordpress_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WordPressConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/telegram/link":{"post":{"tags":["channels"],"summary":"Start the shared-bot Telegram connect flow","description":"Returns a t.me deep link that opens a private chat with the shared Cadencz bot, carrying a signed, short-lived token that identifies the workspace. Telegram only ever echoes deep-link payloads back on a private /start — there's no equivalent for adding a bot to a channel — so the user is asked to add the bot to their channel afterward, from Telegram's own Administrators screen. Our webhook links the two events by the Telegram user id common to both.","operationId":"telegram_link_api_v1_channels_connect_telegram_link_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramLinkResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/telegram":{"post":{"tags":["channels"],"summary":"Connect a Telegram channel","description":"Validates a Telegram bot token and target chat, then stores the token encrypted. The bot must be an admin of the channel/group.","operationId":"connect_telegram_api_v1_channels_connect_telegram_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TelegramConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChannelRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/reddit/start":{"post":{"tags":["channels"],"summary":"Start Reddit OAuth","description":"Creates a signed Reddit OAuth state and returns the Reddit authorization URL. Users approve access on Reddit; they do not enter Reddit credentials in Cadencz.","operationId":"start_reddit_oauth_api_v1_channels_connect_reddit_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedditOAuthStartResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/mastodon/start":{"post":{"tags":["channels"],"summary":"Start Mastodon OAuth","description":"Registers a Cadencz app on the given Mastodon instance and returns that instance's OAuth approval URL.","operationId":"start_mastodon_oauth_api_v1_channels_connect_mastodon_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MastodonOAuthStartRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthStartResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/connect/{provider}/start":{"post":{"tags":["channels"],"summary":"Start OAuth for a social provider","description":"Signs an OAuth state and returns the provider's authorization URL. Supported: x, linkedin, threads, facebook, discord.","operationId":"start_oauth_api_v1_channels_connect__provider__start_post","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string","title":"Provider"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/OAuthStartRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthStartResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/{channel_id}":{"delete":{"tags":["channels"],"summary":"Disconnect a channel","description":"Marks a connected publishing channel as disconnected for the current workspace.","operationId":"disconnect_channel_api_v1_channels__channel_id__delete","parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","title":"Channel Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/{channel_id}/threads/insights":{"get":{"tags":["channels"],"summary":"Read account-level Threads insights","description":"Calls `GET /{threads-user-id}/threads_insights` for a connected Threads channel and returns the metrics Meta reports for the account as a whole — reach, engagement, and follower count.\n\nRequires the `threads_manage_insights` permission. A channel connected before that scope was requested answers 409 and needs reconnecting.","operationId":"read_threads_account_insights_api_v1_channels__channel_id__threads_insights_get","parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","title":"Channel Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadsAccountInsightsResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/channels/{channel_id}/threads/profile-lookup":{"get":{"tags":["channels"],"summary":"Look up a public Threads profile","description":"Calls `GET /profile_lookup` using a connected Threads channel's token to read another creator's public profile and their last seven days of public engagement.\n\nRequires the `threads_profile_discovery` permission. Meta only discloses public profiles with at least 100 followers; anything else returns `found: false` rather than an error.","operationId":"lookup_threads_profile_api_v1_channels__channel_id__threads_profile_lookup_get","parameters":[{"name":"channel_id","in":"path","required":true,"schema":{"type":"string","title":"Channel Id"}},{"name":"username","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"Threads handle to look up, with or without the leading @.","examples":["zuck"],"title":"Username"},"description":"Threads handle to look up, with or without the leading @."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThreadsProfileLookupResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/analytics/advice":{"post":{"tags":["analytics"],"summary":"Get AI optimization recommendations from your analytics","description":"Runs the analysis-layer skills over the workspace's published-post metrics and returns tiered recommendations (quick wins, strategic shifts, experiments, stop-doing). Never asks the user; works with whatever data exists.","operationId":"get_analytics_advice_api_v1_analytics_advice_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsAdvice"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/analytics/posts":{"get":{"tags":["analytics"],"summary":"List published posts with live links + metrics","description":"Every post that actually published, newest first, with its live permalink and latest captured engagement metrics. Powers the calendar's Posted history list.","operationId":"list_published_posts_api_v1_analytics_posts_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AnalyticsPublishedPost"},"title":"Response List Published Posts Api V1 Analytics Posts Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/analytics/summary":{"get":{"tags":["analytics"],"summary":"Get real workspace analytics","description":"Returns analytics from persisted workspace data only. Social performance metrics appear after platform metric ingestion is implemented.","operationId":"get_analytics_summary_api_v1_analytics_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsSummary"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/analytics/momentum":{"get":{"tags":["analytics"],"summary":"Published posts and their reach, day by day","description":"The Home page's momentum read for a workspace that has already published. Post counts are exact and unlimited; reach and engagement follow the plan's measured platforms, like `/analytics/summary`.","operationId":"get_analytics_momentum_api_v1_analytics_momentum_get","parameters":[{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","maximum":26,"minimum":4,"default":12,"title":"Weeks"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsMomentum"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/analytics/refresh":{"post":{"tags":["analytics"],"summary":"Refresh post analytics across every connected platform","description":"Reads engagement for posts Cadencz published in the last 30 days and stores a snapshot per post.\n\n**One platform failing never stops the others.** Each platform — and each channel within it — is fetched independently, and the response names exactly what failed and why. A 200 with `status: \"partial\"` means some platforms refreshed and others did not; read `platforms[]` for the detail.\n\nTwo modes. `force=true` is the Refresh button: the user asked, so cadence gating is bypassed. `force=false` is arrival — opening Analytics, or signing in — and refreshes only if the data is older than the plan's interval, returning `status: \"skipped\"` otherwise. Either way a full-history read is still weekly; pressing refresh buys fresh numbers, not deeper ones.","operationId":"refresh_post_analytics_api_v1_analytics_refresh_post","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"True for the Refresh button. False for the automatic refresh when a page loads, which respects the plan's refresh interval.","default":true,"title":"Force"},"description":"True for the Refresh button. False for the automatic refresh when a page loads, which respects the plan's refresh interval."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsRefreshResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains":{"get":{"tags":["brains"],"summary":"List Brains","operationId":"list_brains_api_v1_brains_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BrainRead"},"type":"array","title":"Response List Brains Api V1 Brains Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"post":{"tags":["brains"],"summary":"Create a Brain","operationId":"create_brain_api_v1_brains_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains/{brain_id}":{"get":{"tags":["brains"],"summary":"Get a Brain","operationId":"get_brain_api_v1_brains__brain_id__get","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"delete":{"tags":["brains"],"summary":"Delete a Brain","operationId":"delete_brain_api_v1_brains__brain_id__delete","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains/{brain_id}/sources":{"get":{"tags":["brains"],"summary":"List Brain sources","operationId":"list_brain_sources_api_v1_brains__brain_id__sources_get","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BrainSourceRead"},"title":"Response List Brain Sources Api V1 Brains  Brain Id  Sources Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"post":{"tags":["brains"],"summary":"Add a Brain source","operationId":"create_brain_source_api_v1_brains__brain_id__sources_post","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainSourceCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainSourceRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains/{brain_id}/sources/{source_id}":{"patch":{"tags":["brains"],"summary":"Update a Brain source","operationId":"update_brain_source_api_v1_brains__brain_id__sources__source_id__patch","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainSourceUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainSourceRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"delete":{"tags":["brains"],"summary":"Delete a Brain source","operationId":"delete_brain_source_api_v1_brains__brain_id__sources__source_id__delete","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}},{"name":"source_id","in":"path","required":true,"schema":{"type":"string","title":"Source Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains/{brain_id}/conversations":{"get":{"tags":["brain conversations"],"summary":"List a Brain's conversations","operationId":"list_conversations_api_v1_brains__brain_id__conversations_get","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BrainConversationRead"},"title":"Response List Conversations Api V1 Brains  Brain Id  Conversations Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"post":{"tags":["brain conversations"],"summary":"Start a Brain conversation","operationId":"start_conversation_api_v1_brains__brain_id__conversations_post","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainConversationCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainConversationRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains/{brain_id}/conversations/{conversation_id}":{"get":{"tags":["brain conversations"],"summary":"Get a Brain conversation","operationId":"get_conversation_api_v1_brains__brain_id__conversations__conversation_id__get","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}},{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainConversationDetail"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains/{brain_id}/conversations/{conversation_id}/handoff/{message_id}":{"get":{"tags":["brain conversations"],"summary":"Load one Brain draft for Compose","operationId":"get_conversation_handoff_api_v1_brains__brain_id__conversations__conversation_id__handoff__message_id__get","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}},{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainConversationHandoff"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/brains/{brain_id}/conversations/{conversation_id}/messages":{"post":{"tags":["brain conversations"],"summary":"Send a message to a Brain","operationId":"send_message_api_v1_brains__brain_id__conversations__conversation_id__messages_post","parameters":[{"name":"brain_id","in":"path","required":true,"schema":{"type":"string","title":"Brain Id"}},{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainChatRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrainChatResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/generation/text":{"post":{"tags":["generation"],"summary":"Generate platform-specific post copy","description":"Runs the Cadencz agent graph (per platform) to turn one idea into publish-ready copy — in the workspace's learned voice, shaped to each platform's rules, and checked by the critic. Uses the tiered model router (no direct provider key needed).","operationId":"generate_text_api_v1_generation_text_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextGenerationRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextGenerationResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/generation/ideas":{"post":{"tags":["generation"],"summary":"Brainstorm a batch of post ideas","description":"Turns the workspace strategy (and an optional seed topic) into a batch of concrete, on-strategy post ideas to draft next — ending the blank-page problem. Never asks the user anything; infers from stored strategy.","operationId":"generate_ideas_api_v1_generation_ideas_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdeasRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdeasResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/generation/variants/{variant_id}/review":{"post":{"tags":["generation"],"summary":"AI review of a single post","description":"Reviews one post variant and returns a few applyable improvement suggestions (each with the post already rewritten to apply it) plus a brand-voice verdict. One smart-tier call; grounded in the workspace's strategy, voice, and writing skills.","operationId":"review_variant_api_v1_generation_variants__variant_id__review_post","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostReviewResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"get":{"tags":["generation"],"summary":"Latest saved AI review of a post","description":"Returns the most recent completed AI review for this variant, free of charge. Reviews spend allowance to run, so surfaces hydrate from here instead of discarding a paid result on every tab switch. 404 when none has run yet.","operationId":"read_variant_review_api_v1_generation_variants__variant_id__review_get","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostReviewResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/posts":{"get":{"tags":["posts"],"summary":"List posts","description":"Returns posts and variants for the current user's active workspace.","operationId":"list_posts_api_v1_posts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/PostRead"},"type":"array","title":"Response List Posts Api V1 Posts Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"post":{"tags":["posts"],"summary":"Create a post","description":"Creates a post and one or more channel-specific variants. Variants with `scheduled_at` are persisted for the Cloudflare Cron worker.","operationId":"create_post_api_v1_posts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/posts/published":{"get":{"tags":["posts"],"summary":"What has gone out, a page at a time","description":"Published variants newest first, ten by default, with their media resolved. Pass the previous page's `next_cursor` as `before` for the next page.","operationId":"list_published_api_v1_posts_published_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}},{"name":"before","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Before"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishedPageRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/posts/counts":{"get":{"tags":["posts"],"summary":"Get lightweight post counts for the app shell","operationId":"post_counts_api_v1_posts_counts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostCounts"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/variants/{variant_id}":{"patch":{"tags":["posts"],"summary":"Update a post variant","description":"Updates editable copy or media for a draft, scheduled, or failed variant.","operationId":"update_variant_api_v1_variants__variant_id__patch","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateVariantRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]},"delete":{"tags":["posts"],"summary":"Delete a post variant","description":"Permanently deletes a variant (and its schedule). Published variants can't be deleted.","operationId":"delete_variant_api_v1_variants__variant_id__delete","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/variants/{variant_id}/schedule":{"post":{"tags":["posts"],"summary":"Schedule a variant","description":"Schedules or reschedules a variant for the Cloudflare Cron worker.","operationId":"schedule_variant_api_v1_variants__variant_id__schedule_post","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleVariantRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/variants/{variant_id}/cancel":{"post":{"tags":["posts"],"summary":"Cancel a variant","description":"Cancels a draft, scheduled, or failed variant before publishing has started.","operationId":"cancel_variant_api_v1_variants__variant_id__cancel_post","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/variants/{variant_id}/publish-now":{"post":{"tags":["posts"],"summary":"Publish a variant now","description":"Publishes a draft, scheduled, or failed variant immediately and synchronously — the response reflects the real publish outcome rather than waiting for the scheduler. Also the retry path for a failed post: it posts instantly instead of waiting for its (past) scheduled time.","operationId":"publish_now_api_v1_variants__variant_id__publish_now_post","parameters":[{"name":"variant_id","in":"path","required":true,"schema":{"type":"string","title":"Variant Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VariantRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The platform rejected the publish; safe to retry."},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/posts/{post_id}":{"delete":{"tags":["posts"],"summary":"Delete a post and all its variants","description":"Permanently deletes a post and every variant/schedule under it (published excepted).","operationId":"delete_post_api_v1_posts__post_id__delete","parameters":[{"name":"post_id","in":"path","required":true,"schema":{"type":"string","title":"Post Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"The requested resource was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/plans":{"get":{"tags":["billing"],"summary":"List billing plans","description":"Returns the Dodo Payments subscription catalog and allowance definitions for the frontend.","operationId":"plans_api_v1_billing_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlansResponse"}}}}}}},"/api/v1/billing/allowances":{"get":{"tags":["billing"],"summary":"Get current monthly plan allowances","operationId":"allowances_api_v1_billing_allowances_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanAllowanceRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/usage":{"get":{"tags":["billing"],"summary":"Get credit usage summary","description":"Returns cumulative credit usage for the authenticated user, plus current workspace usage and project/Brain-level usage.","operationId":"usage_api_v1_billing_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditUsageResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/subscription":{"get":{"tags":["billing"],"summary":"Get current workspace subscription","description":"Returns the current workspace subscription, or a no-plan state before checkout.","operationId":"subscription_api_v1_billing_subscription_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/purchases":{"get":{"tags":["billing"],"summary":"List billing purchases","description":"Returns successful Dodo purchases recorded for the current workspace.","operationId":"purchases_api_v1_billing_purchases_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BillingPurchaseRead"},"type":"array","title":"Response Purchases Api V1 Billing Purchases Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/ledger":{"get":{"tags":["billing"],"summary":"List credit ledger entries","description":"Returns the newest credit ledger entries for the authenticated user's workspaces.","operationId":"ledger_api_v1_billing_ledger_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/CreditLedgerEntryRead"},"type":"array","title":"Response Ledger Api V1 Billing Ledger Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/balance":{"get":{"tags":["billing"],"summary":"Get current workspace credit balance","operationId":"balance_api_v1_billing_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditBalanceResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/model-runs":{"get":{"tags":["billing"],"summary":"List model generation usage","description":"Returns the newest provider calls for the authenticated user's workspaces, including token usage, estimated provider cost, and the pricing source used.","operationId":"model_runs_api_v1_billing_model_runs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ModelRunRead"},"type":"array","title":"Response Model Runs Api V1 Billing Model Runs Get"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/reconcile":{"post":{"tags":["billing"],"summary":"Reconcile the subscription against Dodo","description":"Fetches the workspace's subscription facts from Dodo and updates the local mirror: status, plan, renewal date, cancellation flag — and which subscription the workspace even has, matched via checkout metadata when the mirror never learned of a purchase. Webhooks remain the only path that grants credits; this syncs facts, which are idempotent. The client calls it after returning from checkout and on billing-page load, so the page is truthful even where webhooks cannot reach (local development) or have not arrived yet (production).","operationId":"reconcile_api_v1_billing_reconcile_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Create checkout session","description":"Creates a Dodo Payments subscription checkout. There is no trial: the Free plan is what a customer tries the product on, and checkout charges immediately.","operationId":"checkout_api_v1_billing_checkout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/checkout/{attempt_id}":{"delete":{"tags":["billing"],"summary":"Abandon the current checkout session","description":"Record a local overlay close without discarding payment correlation.\n\nClosing the browser overlay does not cancel the external Dodo session: a\npayment can still complete afterward. Retain the attempt until a signed\nactivation consumes it or its local lifetime expires, so that late success\ncan still be correlated and a different live checkout cannot race it.","operationId":"abandon_checkout_api_v1_billing_checkout__attempt_id__delete","parameters":[{"name":"attempt_id","in":"path","required":true,"schema":{"type":"string","title":"Attempt Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/plan-change/preview":{"post":{"tags":["billing"],"summary":"Quote a plan change before submitting it","description":"Returns Dodo's own quote for switching to `tier`. Every plan change is effective immediately: an upgrade charges the prorated difference on Dodo's hosted payment page, a downgrade charges nothing and leaves the unused value as credit toward future renewals. This is what the confirmation dialog shows before the customer commits to anything.","operationId":"preview_plan_change_api_v1_billing_plan_change_preview_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanChangePreviewRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanChangePreviewRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/portal":{"post":{"tags":["billing"],"summary":"Create customer portal session","description":"Creates a Dodo Payments customer portal link for the authenticated workspace.","operationId":"portal_api_v1_billing_portal_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalResponse"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/subscription/cancel":{"post":{"tags":["billing"],"summary":"Cancel the subscription at the end of the billing period","description":"Schedules the cancellation with Dodo. The plan stays fully active and paid-for until the period the customer already paid for runs out, then simply does not renew — no further charges. Reversible any time before the period ends via the resume endpoint, and choosing any plan also resumes it.","operationId":"cancel_subscription_api_v1_billing_subscription_cancel_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelSubscriptionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/billing/subscription/resume":{"post":{"tags":["billing"],"summary":"Undo a scheduled cancellation","description":"Lifts a pending end-of-period cancellation so the plan keeps renewing. Charges nothing by itself — the next renewal bills on its normal date.","operationId":"resume_subscription_api_v1_billing_subscription_resume_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionRead"}}}},"401":{"description":"Missing or invalid Supabase bearer token.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"The requested state transition is not allowed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"502":{"description":"The upstream provider rejected the request.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"SupabaseBearerAuth":[]}]}},"/api/v1/webhooks/dodo":{"post":{"tags":["webhooks"],"summary":"Receive Dodo Payments webhook","description":"Receives Dodo Payments webhook events, verifies the provider signature in deployed environments, and stores each event idempotently.","operationId":"dodo_webhook_api_v1_webhooks_dodo_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object"},"example":{"id":"evt_123","type":"payment.succeeded","data":{"customer_id":"cus_123"}}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DodoWebhookResponse"}}}},"400":{"description":"The request payload is invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"security":[{"DodoWebhookSignature":[]}]}},"/api/v1/jobs/publish-due":{"post":{"tags":["jobs"],"summary":"Publish due scheduled variants","description":"Cloudflare Cron callback endpoint. Authenticates with `WORKER_SECRET`, claims due scheduled variants from the database, and publishes them. This is the preferred scheduler path for posts scheduled more than a few days ahead.","operationId":"publish_due_job_api_v1_jobs_publish_due_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishDueJobResponse"}}}},"401":{"description":"Missing or invalid worker secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/jobs/plan-week":{"post":{"tags":["jobs"],"summary":"Auto-generate this week's plan for workspaces due right now","description":"Cloudflare Cron callback. **Must be scheduled hourly (`0 * * * *`)**, not weekly.\n\nEach workspace picks its own planning weekday, hour, and timezone in its automation settings; this endpoint plans only the workspaces whose configured hour is the current one. An hourly tick is what turns a single global cron into per-workspace scheduling without a job queue — run it weekly and almost every workspace is skipped.\n\nAuthenticates with `WORKER_SECRET`. Auto-planning is opt-in per workspace and is idempotent: a workspace that already has a plan for the current week is skipped.","operationId":"plan_week_job_api_v1_jobs_plan_week_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanWeekJobResponse"}}}},"401":{"description":"Missing or invalid worker secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/jobs/replan-months":{"post":{"tags":["jobs"],"summary":"Re-plan the month for workspaces whose plan has lapsed","description":"Cloudflare Cron callback. Safe to run hourly: the `generated_for` stamp on each stored month plan makes the work once-per-workspace-per-month, so every call after the first is a cheap no-op.\n\nEach re-plan reads the Brain profile plus last month's analytics and published posts, and draws one Brain-analysis allowance unit — a workspace with none left (Free after its lifetime unit) is skipped, not failed. Authenticates with `WORKER_SECRET`.","operationId":"replan_months_job_api_v1_jobs_replan_months_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MonthReplanJobResponse"}}}},"401":{"description":"Missing or invalid worker secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/jobs/refresh-analytics":{"post":{"tags":["jobs"],"summary":"Refresh engagement metrics for recently published posts","description":"Cloudflare Cron callback. **Schedule hourly (`15 * * * *`)**, not daily.\n\nThe tick is hourly but each platform decides for itself whether it is due, based on what its API costs: free, generously rate-limited reads (Bluesky, Mastodon, Reddit, Threads, Facebook, dev.to, LinkedIn) refresh every hour, while X — whose tweet lookup requires a paid tier with a monthly read quota — refreshes once a day. Running this hourly is what lets one cron serve both cadences; running it daily would silently downgrade every platform to daily.\n\nOnly posts Cadencz published, and only the last 30 days, are read. A failure on one platform or channel never stops the rest — the response reports each outcome separately.\n\nAuthenticates with `WORKER_SECRET`.","operationId":"refresh_analytics_job_api_v1_jobs_refresh_analytics_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshAnalyticsJobResponse"}}}},"401":{"description":"Missing or invalid worker secret.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"503":{"description":"Required infrastructure or provider config is unavailable.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/free-tools/generate":{"post":{"tags":["free tools"],"summary":"Generate","operationId":"generate_api_v1_free_tools_generate_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/free-tools/drafts":{"get":{"tags":["free tools"],"summary":"List Drafts","operationId":"list_drafts_api_v1_free_tools_drafts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["free tools"],"summary":"Import Draft","operationId":"import_draft_api_v1_free_tools_drafts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DraftInput"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/free-tools/drafts/{ident}/prepare":{"post":{"tags":["free tools"],"summary":"Prepare Draft","operationId":"prepare_draft_api_v1_free_tools_drafts__ident__prepare_post","parameters":[{"name":"ident","in":"path","required":true,"schema":{"type":"string","title":"Ident"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromoteInput"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/oauth/consent":{"get":{"tags":["mcp oauth"],"summary":"Describe Consent","description":"What the consent page shows: which app is asking, and where it returns.","operationId":"describe_consent_api_v1_oauth_consent_get","parameters":[{"name":"request","in":"query","required":true,"schema":{"type":"string","minLength":10,"maxLength":8000,"title":"Request"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentDescribeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["mcp oauth"],"summary":"Give Consent","description":"Approve or deny, as the signed-in person, for their current workspace.","operationId":"give_consent_api_v1_oauth_consent_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["health"],"summary":"Health check","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}},"/":{"get":{"tags":["health"],"summary":"Root health check","operationId":"health__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}}}}}},"components":{"schemas":{"AccountGrantRead":{"properties":{"id":{"type":"string","title":"Id"},"label":{"type":"string","title":"Label"}},"type":"object","required":["id","label"],"title":"AccountGrantRead","description":"A capability an owner can hand over, named for the UI that renders it."},"AccountInviteRead":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role"},"prefix":{"type":"string","title":"Prefix"},"expiresAt":{"type":"string","title":"Expiresat"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions","default":[]}},"type":"object","required":["id","email","role","prefix","expiresAt"],"title":"AccountInviteRead"},"AccountMemberRead":{"properties":{"id":{"type":"string","title":"Id"},"userId":{"type":"string","title":"Userid"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"role":{"type":"string","title":"Role"},"status":{"type":"string","title":"Status"},"isOwner":{"type":"boolean","title":"Isowner"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions","default":[]}},"type":"object","required":["id","userId","email","name","role","status","isOwner"],"title":"AccountMemberRead"},"AccountMembersResponse":{"properties":{"members":{"items":{"$ref":"#/components/schemas/AccountMemberRead"},"type":"array","title":"Members"},"invites":{"items":{"$ref":"#/components/schemas/AccountInviteRead"},"type":"array","title":"Invites"},"seatCap":{"type":"integer","title":"Seatcap"}},"type":"object","required":["members","invites","seatCap"],"title":"AccountMembersResponse"},"AdminChannelUsage":{"properties":{"platform":{"type":"string","title":"Platform"},"enabled":{"type":"boolean","title":"Enabled"},"connect_enabled":{"type":"boolean","title":"Connect Enabled"},"publish_enabled":{"type":"boolean","title":"Publish Enabled"},"connected_accounts":{"type":"integer","title":"Connected Accounts"},"workspaces":{"type":"integer","title":"Workspaces"},"published_this_month":{"type":"integer","title":"Published This Month"}},"type":"object","required":["platform","enabled","connect_enabled","publish_enabled","connected_accounts","workspaces","published_this_month"],"title":"AdminChannelUsage"},"AdminConfigAuditEntry":{"properties":{"id":{"type":"string","title":"Id"},"at":{"type":"string","title":"At"},"version":{"type":"integer","title":"Version"},"section":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section"},"action":{"type":"string","title":"Action"},"changed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Changed By"},"changed_by_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Changed By Email"},"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"},"changes":{"items":{"$ref":"#/components/schemas/AdminConfigChange"},"type":"array","title":"Changes"}},"type":"object","required":["id","at","version","section","action","changed_by","changed_by_email","note","changes"],"title":"AdminConfigAuditEntry"},"AdminConfigChange":{"properties":{"path":{"type":"string","title":"Path"},"before":{"title":"Before"},"after":{"title":"After"}},"type":"object","required":["path"],"title":"AdminConfigChange"},"AdminConfigPreviewResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"errors":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Errors"},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings"},"changes":{"items":{"$ref":"#/components/schemas/AdminConfigChange"},"type":"array","title":"Changes"}},"type":"object","required":["valid","errors","warnings","changes"],"title":"AdminConfigPreviewResponse","description":"What a save would do, without doing it."},"AdminConfigResetRequest":{"properties":{"section":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section"},"expected_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Version"},"confirm":{"type":"boolean","title":"Confirm","default":false}},"type":"object","title":"AdminConfigResetRequest"},"AdminConfigResponse":{"properties":{"version":{"type":"integer","title":"Version"},"config":{"additionalProperties":true,"type":"object","title":"Config"},"defaults":{"additionalProperties":true,"type":"object","title":"Defaults"},"schema":{"additionalProperties":true,"type":"object","title":"Schema"},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"},"updated_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated By"},"updated_by_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated By Email"},"migration_required":{"type":"boolean","title":"Migration Required","default":false},"warnings":{"items":{"type":"string"},"type":"array","title":"Warnings","default":[]}},"type":"object","required":["version","config","defaults","schema","updated_at","updated_by","updated_by_email"],"title":"AdminConfigResponse","description":"Everything the admin screen needs in one round trip."},"AdminConfigSaveRequest":{"properties":{"config":{"additionalProperties":true,"type":"object","title":"Config"},"expected_version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expected Version"},"section":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Section"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"},"confirm":{"type":"boolean","title":"Confirm","default":false}},"type":"object","required":["config"],"title":"AdminConfigSaveRequest"},"AdminExpectedVsActual":{"properties":{"period_start":{"type":"string","title":"Period Start"},"as_of":{"type":"string","title":"As Of"},"expected_full_month_cost_usd_micros":{"type":"integer","title":"Expected Full Month Cost Usd Micros"},"expected_cost_to_date_usd_micros":{"type":"integer","title":"Expected Cost To Date Usd Micros"},"actual_cost_to_date_usd_micros":{"type":"integer","title":"Actual Cost To Date Usd Micros"},"variance_usd_micros":{"type":"integer","title":"Variance Usd Micros"},"actual_percent_of_expected":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Actual Percent Of Expected"},"basis":{"type":"string","title":"Basis"}},"type":"object","required":["period_start","as_of","expected_full_month_cost_usd_micros","expected_cost_to_date_usd_micros","actual_cost_to_date_usd_micros","variance_usd_micros","actual_percent_of_expected","basis"],"title":"AdminExpectedVsActual"},"AdminFinancialPeriod":{"properties":{"period_start":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Period Start"},"period_end":{"type":"string","title":"Period End"},"recorded_revenue_usd_micros":{"type":"integer","title":"Recorded Revenue Usd Micros"},"model_cost_usd_micros":{"type":"integer","title":"Model Cost Usd Micros"},"contribution_usd_micros":{"type":"integer","title":"Contribution Usd Micros"},"model_runs":{"type":"integer","title":"Model Runs"},"recorded_payments":{"type":"integer","title":"Recorded Payments"}},"type":"object","required":["period_start","period_end","recorded_revenue_usd_micros","model_cost_usd_micros","contribution_usd_micros","model_runs","recorded_payments"],"title":"AdminFinancialPeriod"},"AdminOverviewResponse":{"properties":{"users":{"type":"integer","title":"Users"},"admins":{"type":"integer","title":"Admins"},"workspaces":{"type":"integer","title":"Workspaces"},"active_subscriptions":{"type":"integer","title":"Active Subscriptions"},"model_runs":{"type":"integer","title":"Model Runs"},"monthly_ai_generations_used":{"type":"integer","title":"Monthly Ai Generations Used"},"credits_granted":{"type":"integer","title":"Credits Granted"},"credits_used":{"type":"integer","title":"Credits Used"},"credit_balance":{"type":"integer","title":"Credit Balance"},"estimated_revenue_usd":{"type":"number","title":"Estimated Revenue Usd"},"estimated_provider_cost_usd_micros":{"type":"integer","title":"Estimated Provider Cost Usd Micros"},"estimated_margin_usd_micros":{"type":"integer","title":"Estimated Margin Usd Micros"},"current_month_actual":{"$ref":"#/components/schemas/AdminFinancialPeriod"},"lifetime_actual":{"$ref":"#/components/schemas/AdminFinancialPeriod"},"expected_vs_actual":{"$ref":"#/components/schemas/AdminExpectedVsActual"},"config_version":{"type":"integer","title":"Config Version"},"plan_economics":{"items":{"$ref":"#/components/schemas/AdminPlanEconomics"},"type":"array","title":"Plan Economics"},"plan_adoption":{"items":{"$ref":"#/components/schemas/AdminPlanAdoption"},"type":"array","title":"Plan Adoption"},"channels":{"items":{"$ref":"#/components/schemas/AdminChannelUsage"},"type":"array","title":"Channels"},"workspaces_usage":{"items":{"$ref":"#/components/schemas/AdminWorkspaceUsage"},"type":"array","title":"Workspaces Usage"}},"type":"object","required":["users","admins","workspaces","active_subscriptions","model_runs","monthly_ai_generations_used","credits_granted","credits_used","credit_balance","estimated_revenue_usd","estimated_provider_cost_usd_micros","estimated_margin_usd_micros","current_month_actual","lifetime_actual","expected_vs_actual","config_version","plan_economics","plan_adoption","channels","workspaces_usage"],"title":"AdminOverviewResponse"},"AdminPlanAdoption":{"properties":{"tier":{"type":"string","title":"Tier"},"name":{"type":"string","title":"Name"},"enabled":{"type":"boolean","title":"Enabled"},"purchasable":{"type":"boolean","title":"Purchasable"},"active_subscriptions":{"type":"integer","title":"Active Subscriptions"},"trialing":{"type":"boolean","title":"Trialing","default":false}},"type":"object","required":["tier","name","enabled","purchasable","active_subscriptions"],"title":"AdminPlanAdoption"},"AdminPlanEconomics":{"properties":{"tier":{"type":"string","title":"Tier"},"name":{"type":"string","title":"Name"},"monthly_price_usd_micros":{"type":"integer","title":"Monthly Price Usd Micros"},"yearly_price_usd_micros":{"type":"integer","title":"Yearly Price Usd Micros"},"premium_actions":{"type":"integer","title":"Premium Actions"},"plan_runs":{"type":"integer","title":"Plan Runs"},"posts_per_plan":{"type":"integer","title":"Posts Per Plan"},"planned_post_generations":{"type":"integer","title":"Planned Post Generations"},"total_ai_generations":{"type":"integer","title":"Total Ai Generations"},"remaining_ai_generations":{"type":"integer","title":"Remaining Ai Generations"},"x_posts":{"type":"integer","title":"X Posts"},"x_posts_with_links":{"type":"integer","title":"X Posts With Links"},"channel_cap":{"type":"integer","title":"Channel Cap"},"active_x_accounts":{"type":"integer","title":"Active X Accounts"},"ai_analytics_insights":{"type":"integer","title":"Ai Analytics Insights"},"ai_post_generation_cost_usd_micros":{"type":"integer","title":"Ai Post Generation Cost Usd Micros"},"planner_cost_usd_micros":{"type":"integer","title":"Planner Cost Usd Micros"},"planner_recovery_cost_usd_micros":{"type":"integer","title":"Planner Recovery Cost Usd Micros"},"premium_planner_runs":{"type":"integer","title":"Premium Planner Runs"},"x_publish_cost_usd_micros":{"type":"integer","title":"X Publish Cost Usd Micros"},"x_entitlement_cost_usd_micros":{"type":"integer","title":"X Entitlement Cost Usd Micros"},"ai_analytics_cost_usd_micros":{"type":"integer","title":"Ai Analytics Cost Usd Micros"},"estimated_provider_cost_usd_micros":{"type":"integer","title":"Estimated Provider Cost Usd Micros"},"estimated_margin_usd_micros":{"type":"integer","title":"Estimated Margin Usd Micros"},"estimated_gross_margin_percent":{"type":"number","title":"Estimated Gross Margin Percent"},"estimated_yearly_provider_cost_usd_micros":{"type":"integer","title":"Estimated Yearly Provider Cost Usd Micros"},"estimated_yearly_margin_usd_micros":{"type":"integer","title":"Estimated Yearly Margin Usd Micros"},"estimated_yearly_gross_margin_percent":{"type":"number","title":"Estimated Yearly Gross Margin Percent"},"over_allocated":{"type":"boolean","title":"Over Allocated"},"excludes_infrastructure":{"type":"boolean","title":"Excludes Infrastructure"},"forecast_basis":{"type":"string","title":"Forecast Basis"},"observed_ai_unit_cost_usd_micros":{"type":"integer","title":"Observed Ai Unit Cost Usd Micros"},"observed_model_runs":{"type":"integer","title":"Observed Model Runs"}},"type":"object","required":["tier","name","monthly_price_usd_micros","yearly_price_usd_micros","premium_actions","plan_runs","posts_per_plan","planned_post_generations","total_ai_generations","remaining_ai_generations","x_posts","x_posts_with_links","channel_cap","active_x_accounts","ai_analytics_insights","ai_post_generation_cost_usd_micros","planner_cost_usd_micros","planner_recovery_cost_usd_micros","premium_planner_runs","x_publish_cost_usd_micros","x_entitlement_cost_usd_micros","ai_analytics_cost_usd_micros","estimated_provider_cost_usd_micros","estimated_margin_usd_micros","estimated_gross_margin_percent","estimated_yearly_provider_cost_usd_micros","estimated_yearly_margin_usd_micros","estimated_yearly_gross_margin_percent","over_allocated","excludes_infrastructure","forecast_basis","observed_ai_unit_cost_usd_micros","observed_model_runs"],"title":"AdminPlanEconomics"},"AdminProvisionRequest":{"properties":{"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"grant_credits":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Grant Credits"},"workspace_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workspace Id"}},"type":"object","title":"AdminProvisionRequest","description":"Admin-only dev tool: grant credits and/or activate a plan without Dodo.\n\nLets an admin reflect a purchase or plan locally when the Dodo webhook\ncannot reach the dev machine. Not a substitute for real payment.","example":{"grant_credits":350,"tier":"solo"}},"AdminUserRow":{"properties":{"user_reference_number":{"type":"string","title":"User Reference Number"},"email":{"type":"string","title":"Email"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"is_admin":{"type":"boolean","title":"Is Admin"},"created_at":{"type":"string","title":"Created At"},"workspaces":{"type":"integer","title":"Workspaces"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"}},"type":"object","required":["user_reference_number","email","name","is_admin","created_at","workspaces","tier"],"title":"AdminUserRow"},"AdminWorkspaceUsage":{"properties":{"workspace_id":{"type":"string","title":"Workspace Id"},"workspace_name":{"type":"string","title":"Workspace Name"},"owner_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Owner Email"},"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"monthly_ai_generations_used":{"type":"integer","title":"Monthly Ai Generations Used"},"monthly_ai_generations_cap":{"type":"integer","title":"Monthly Ai Generations Cap"},"credits_granted":{"type":"integer","title":"Credits Granted"},"credits_used":{"type":"integer","title":"Credits Used"},"credit_balance":{"type":"integer","title":"Credit Balance"},"model_runs":{"type":"integer","title":"Model Runs"},"provider_cost_usd_micros":{"type":"integer","title":"Provider Cost Usd Micros"},"estimated_revenue_usd":{"type":"number","title":"Estimated Revenue Usd"}},"type":"object","required":["workspace_id","workspace_name","owner_email","tier","status","monthly_ai_generations_used","monthly_ai_generations_cap","credits_granted","credits_used","credit_balance","model_runs","provider_cost_usd_micros","estimated_revenue_usd"],"title":"AdminWorkspaceUsage"},"AgentRunRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"route":{"type":"string","title":"Route","description":"The graph route (stored as the run 'stage')."},"status":{"type":"string","title":"Status"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"input_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Input Text"},"output_json":{"additionalProperties":true,"type":"object","title":"Output Json"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"tokens_used":{"type":"integer","title":"Tokens Used"},"model_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Provider"},"model_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model Name"},"steps":{"items":{"$ref":"#/components/schemas/AgentStepRead"},"type":"array","title":"Steps"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","workspace_id","route","status","tags","input_text","output_json","error","tokens_used","model_provider","model_name","steps","created_at","updated_at"],"title":"AgentRunRead","example":{"created_at":"2026-07-13T10:00:00Z","id":"run_123","input_text":"Write a launch post about Google sign-in.","model_name":"deepseek-chat","model_provider":"deepseek","output_json":{"text":"Google sign-in is live — one tap in, zero password resets."},"route":"answer","status":"succeeded","steps":[],"tags":["#hook"],"tokens_used":56,"updated_at":"2026-07-13T10:00:01Z","workspace_id":"wks_123"}},"AgentRunRequest":{"properties":{"input":{"type":"string","maxLength":8000,"minLength":1,"title":"Input","description":"What the user is asking the agent graph to do.","examples":["Write a launch post about our new Google sign-in."]},"tags":{"items":{"type":"string"},"type":"array","maxItems":12,"title":"Tags","description":"Strict allow-list tags that steer the graph (e.g. #reddit, #hook, #shorten).","examples":[["#hook"]]},"platform":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Platform","description":"Optional target platform for this run.","examples":["twitter"]},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id","description":"Optional Brain id/slug to ground the run in saved product knowledge."},"route":{"type":"string","maxLength":40,"title":"Route","description":"Graph route: 'answer' (strict one-line) or 'generate_post'.","default":"answer"},"read_source":{"type":"string","maxLength":20,"title":"Read Source","description":"Reader source: 'paste' | 'rss' | 'x' (x is flagged off in v1).","default":"paste"},"read_input":{"anyOf":[{"type":"string","maxLength":20000},{"type":"null"}],"title":"Read Input","description":"Optional material for the Reader agent — pasted text or an RSS URL."}},"type":"object","required":["input"],"title":"AgentRunRequest"},"AgentStepRead":{"properties":{"id":{"type":"string","title":"Id"},"sequence":{"type":"integer","title":"Sequence"},"agent_name":{"type":"string","title":"Agent Name"},"tier":{"type":"string","title":"Tier"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"status":{"type":"string","title":"Status"},"attempt":{"type":"integer","title":"Attempt"},"output_json":{"additionalProperties":true,"type":"object","title":"Output Json"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"total_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Tokens"},"cached_input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cached Input Tokens"},"latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Latency Ms"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","sequence","agent_name","tier","provider","model","status","attempt","output_json","error","input_tokens","output_tokens","total_tokens","cached_input_tokens","latency_ms","created_at"],"title":"AgentStepRead"},"AltTextUpdate":{"properties":{"alt_text":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Alt Text"}},"type":"object","title":"AltTextUpdate","description":"Alt text is the only field worth editing after upload — everything else\n(kind, dimensions, bytes) is a property of the file itself."},"AnalyticsAdvice":{"properties":{"summary":{"type":"string","title":"Summary","default":""},"quick_wins":{"items":{"type":"string"},"type":"array","title":"Quick Wins","default":[]},"strategic_shifts":{"items":{"type":"string"},"type":"array","title":"Strategic Shifts","default":[]},"experiments":{"items":{"type":"string"},"type":"array","title":"Experiments","default":[]},"stop_doing":{"items":{"type":"string"},"type":"array","title":"Stop Doing","default":[]}},"type":"object","title":"AnalyticsAdvice"},"AnalyticsChannelSeries":{"properties":{"channel_id":{"type":"string","title":"Channel Id"},"platform":{"type":"string","title":"Platform"},"points":{"items":{"$ref":"#/components/schemas/AnalyticsDailyPoint"},"type":"array","title":"Points"},"total_impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Impressions"},"total_engagements":{"type":"integer","title":"Total Engagements"}},"type":"object","required":["channel_id","platform","points","total_impressions","total_engagements"],"title":"AnalyticsChannelSeries"},"AnalyticsChannelSummary":{"properties":{"id":{"type":"string","title":"Id"},"platform":{"type":"string","title":"Platform"},"handle":{"type":"string","title":"Handle"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"status":{"type":"string","title":"Status"},"followers":{"type":"integer","title":"Followers"}},"type":"object","required":["id","platform","handle","display_name","avatar_url","status","followers"],"title":"AnalyticsChannelSummary"},"AnalyticsDailyPoint":{"properties":{"date":{"type":"string","title":"Date"},"impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Impressions"},"engagements":{"type":"integer","title":"Engagements"}},"type":"object","required":["date","impressions","engagements"],"title":"AnalyticsDailyPoint"},"AnalyticsDailyUsagePoint":{"properties":{"date":{"type":"string","title":"Date"},"runs":{"type":"integer","title":"Runs"},"credits":{"type":"integer","title":"Credits"},"cost_usd_micros":{"type":"integer","title":"Cost Usd Micros"}},"type":"object","required":["date","runs","credits","cost_usd_micros"],"title":"AnalyticsDailyUsagePoint"},"AnalyticsModelSummary":{"properties":{"provider":{"type":"string","title":"Provider"},"model":{"type":"string","title":"Model"},"runs":{"type":"integer","title":"Runs"},"input_tokens":{"type":"integer","title":"Input Tokens"},"output_tokens":{"type":"integer","title":"Output Tokens"},"total_tokens":{"type":"integer","title":"Total Tokens"},"credits_charged":{"type":"integer","title":"Credits Charged"},"cost_usd_micros":{"type":"integer","title":"Cost Usd Micros"}},"type":"object","required":["provider","model","runs","input_tokens","output_tokens","total_tokens","credits_charged","cost_usd_micros"],"title":"AnalyticsModelSummary"},"AnalyticsMomentum":{"properties":{"posts_published":{"type":"integer","title":"Posts Published"},"first_published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Published At"},"weeks":{"type":"integer","title":"Weeks"},"days":{"items":{"$ref":"#/components/schemas/AnalyticsMomentumDay"},"type":"array","title":"Days"},"total_impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Impressions"},"total_engagements":{"type":"integer","title":"Total Engagements"},"all_time_impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"All Time Impressions"},"all_time_engagements":{"type":"integer","title":"All Time Engagements","default":0},"weeks_active":{"type":"integer","title":"Weeks Active"},"current_streak_weeks":{"type":"integer","title":"Current Streak Weeks"},"measured_platforms":{"items":{"type":"string"},"type":"array","title":"Measured Platforms","default":[]}},"type":"object","required":["posts_published","first_published_at","weeks","days","total_impressions","total_engagements","weeks_active","current_streak_weeks"],"title":"AnalyticsMomentum","description":"The \"keep going\" read: what you have shipped and what it has earned,\nday by day, for the last few weeks. Built for a workspace that has already\npublished a few posts — the point is a bar that only ever climbs.\n\nPost counts come from our own rows and are exact. Reach and engagement come\nfrom the latest snapshot per post, attributed to the day the post went out,\nand only for platforms the plan measures — the same rules as the summary."},"AnalyticsMomentumDay":{"properties":{"date":{"type":"string","title":"Date"},"posts":{"type":"integer","title":"Posts"},"impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Impressions"},"engagements":{"type":"integer","title":"Engagements"}},"type":"object","required":["date","posts","impressions","engagements"],"title":"AnalyticsMomentumDay","description":"One calendar day of the momentum grid."},"AnalyticsPublishedPost":{"properties":{"variant_id":{"type":"string","title":"Variant Id"},"post_id":{"type":"string","title":"Post Id"},"channel_id":{"type":"string","title":"Channel Id"},"platform":{"type":"string","title":"Platform"},"handle":{"type":"string","title":"Handle"},"body":{"type":"string","title":"Body"},"permalink":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Permalink"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"likes":{"type":"integer","title":"Likes"},"reposts":{"type":"integer","title":"Reposts"},"replies":{"type":"integer","title":"Replies"},"clicks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Clicks"},"impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Impressions"},"engagements":{"type":"integer","title":"Engagements"},"has_analytics":{"type":"boolean","title":"Has Analytics"}},"type":"object","required":["variant_id","post_id","channel_id","platform","handle","body","permalink","published_at","likes","reposts","replies","clicks","impressions","engagements","has_analytics"],"title":"AnalyticsPublishedPost","description":"One published post for the calendar's \"Posted\" history list — the live\npermalink plus its latest captured engagement metrics."},"AnalyticsRefreshChannel":{"properties":{"channel_id":{"type":"string","title":"Channel Id"},"handle":{"type":"string","title":"Handle"},"status":{"type":"string","enum":["ok","failed"],"title":"Status"},"posts":{"type":"integer","title":"Posts"},"refreshed":{"type":"integer","title":"Refreshed"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["channel_id","handle","status","posts","refreshed"],"title":"AnalyticsRefreshChannel","description":"Per-channel outcome, so a failure names the account it happened on."},"AnalyticsRefreshPlatform":{"properties":{"platform":{"type":"string","title":"Platform"},"status":{"type":"string","enum":["ok","partial","failed","skipped","unsupported"],"title":"Status"},"posts":{"type":"integer","title":"Posts"},"refreshed":{"type":"integer","title":"Refreshed"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"},"channels":{"items":{"$ref":"#/components/schemas/AnalyticsRefreshChannel"},"type":"array","title":"Channels","default":[]}},"type":"object","required":["platform","status","posts","refreshed"],"title":"AnalyticsRefreshPlatform","description":"Per-platform outcome.\n\n`skipped` means the platform is still inside its refresh interval, and\n`unsupported` means the provider exposes no readable metrics at all — neither\nis an error, and the UI should not badge them as one."},"AnalyticsRefreshResponse":{"properties":{"status":{"type":"string","enum":["ok","partial","failed","empty"],"title":"Status"},"refreshed":{"type":"integer","title":"Refreshed"},"posts":{"type":"integer","title":"Posts"},"platforms":{"items":{"$ref":"#/components/schemas/AnalyticsRefreshPlatform"},"type":"array","title":"Platforms"}},"type":"object","required":["status","refreshed","posts","platforms"],"title":"AnalyticsRefreshResponse","example":{"platforms":[{"platform":"bluesky","posts":12,"refreshed":12,"status":"ok"},{"detail":"@acme: X refused the metrics read. Reading tweets requires the Basic tier ($200/month) or higher — the free tier is publish-only.","platform":"x","posts":6,"refreshed":0,"status":"failed"}],"posts":18,"refreshed":12,"status":"partial"}},"AnalyticsSummary":{"properties":{"workspace_id":{"type":"string","title":"Workspace Id"},"connected_channels":{"type":"integer","title":"Connected Channels"},"total_followers":{"type":"integer","title":"Total Followers"},"posts_published":{"type":"integer","title":"Posts Published"},"total_likes":{"type":"integer","title":"Total Likes"},"total_reposts":{"type":"integer","title":"Total Reposts"},"total_replies":{"type":"integer","title":"Total Replies"},"total_clicks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Clicks"},"total_impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Impressions"},"total_engagements":{"type":"integer","title":"Total Engagements"},"ai_generations":{"type":"integer","title":"Ai Generations"},"input_tokens":{"type":"integer","title":"Input Tokens"},"output_tokens":{"type":"integer","title":"Output Tokens"},"total_tokens":{"type":"integer","title":"Total Tokens"},"credits_used":{"type":"integer","title":"Credits Used"},"cost_usd_micros":{"type":"integer","title":"Cost Usd Micros"},"generated_since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Generated Since"},"measured_platforms":{"items":{"type":"string"},"type":"array","title":"Measured Platforms","default":[]},"analytics_history_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Analytics History Days","default":30},"analytics_refresh_interval_minutes":{"type":"integer","title":"Analytics Refresh Interval Minutes","default":1440},"channels":{"items":{"$ref":"#/components/schemas/AnalyticsChannelSummary"},"type":"array","title":"Channels"},"top_posts":{"items":{"$ref":"#/components/schemas/AnalyticsTopPost"},"type":"array","title":"Top Posts"},"channel_series":{"items":{"$ref":"#/components/schemas/AnalyticsChannelSeries"},"type":"array","title":"Channel Series"},"best_time_heatmap":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Best Time Heatmap"},"models":{"items":{"$ref":"#/components/schemas/AnalyticsModelSummary"},"type":"array","title":"Models"},"daily_usage":{"items":{"$ref":"#/components/schemas/AnalyticsDailyUsagePoint"},"type":"array","title":"Daily Usage"}},"type":"object","required":["workspace_id","connected_channels","total_followers","posts_published","total_likes","total_reposts","total_replies","total_clicks","total_impressions","total_engagements","ai_generations","input_tokens","output_tokens","total_tokens","credits_used","cost_usd_micros","generated_since","channels","top_posts","channel_series","best_time_heatmap","models","daily_usage"],"title":"AnalyticsSummary","example":{"ai_generations":3,"channels":[],"connected_channels":1,"cost_usd_micros":900,"credits_used":2,"daily_usage":[],"generated_since":"2026-07-08T10:00:00Z","input_tokens":1000,"models":[],"output_tokens":300,"total_followers":42,"total_tokens":1300,"workspace_id":"wks_123"}},"AnalyticsTopPost":{"properties":{"variant_id":{"type":"string","title":"Variant Id"},"channel_id":{"type":"string","title":"Channel Id"},"platform":{"type":"string","title":"Platform"},"body":{"type":"string","title":"Body"},"captured_at":{"type":"string","format":"date-time","title":"Captured At"},"likes":{"type":"integer","title":"Likes"},"reposts":{"type":"integer","title":"Reposts"},"replies":{"type":"integer","title":"Replies"},"clicks":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Clicks"},"impressions":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Impressions"},"engagements":{"type":"integer","title":"Engagements"}},"type":"object","required":["variant_id","channel_id","platform","body","captured_at","likes","reposts","replies","clicks","impressions","engagements"],"title":"AnalyticsTopPost"},"ApproveItemResponse":{"properties":{"status":{"type":"string","title":"Status"},"item_id":{"type":"string","title":"Item Id"},"post_id":{"type":"string","title":"Post Id"},"variant_ids":{"items":{"type":"string"},"type":"array","title":"Variant Ids","default":[]},"scheduled":{"type":"integer","title":"Scheduled","default":0}},"type":"object","required":["status","item_id","post_id"],"title":"ApproveItemResponse"},"AutomationSettings":{"properties":{"enabled":{"type":"boolean","title":"Enabled","description":"Off by default. Auto-planning spends credits, so it's opt-in.","default":false},"suspended_by_plan":{"type":"boolean","title":"Suspended By Plan","description":"Cadencz turned automation off after plan access was lost. The saved schedule remains, but the customer must explicitly enable it again.","default":false},"auto_write_week":{"type":"boolean","title":"Auto Write Week","description":"Write the week's posts on their own at the planning hour, so the stack always has a fresh week on it. Every plan; bounded by the tier's weekly number and the monthly pool. Distinct from `enabled`, which is the paid Automation feature (rules, auto-approve).","default":true},"plan_weekday":{"type":"integer","maximum":6.0,"minimum":0.0,"title":"Plan Weekday","description":"0 = Monday.","default":0},"plan_hour":{"type":"integer","maximum":23.0,"minimum":0.0,"title":"Plan Hour","description":"Local hour, 24h.","default":6},"timezone":{"type":"string","maxLength":64,"title":"Timezone","description":"IANA zone.","default":"UTC"},"posting_weekdays":{"items":{"type":"integer"},"type":"array","title":"Posting Weekdays","description":"Days posts may be scheduled on. 0 = Monday."},"posting_times":{"items":{"type":"string"},"type":"array","title":"Posting Times","description":"HH:MM slots, cycled through in order."},"day_platforms":{"additionalProperties":{"type":"string"},"type":"object","title":"Day Platforms","description":"Which channel each weekday posts to, keyed by weekday index as a string ('0' = Monday). A day with no entry falls back to the workspace's platform rotation."},"platform_quota":{"additionalProperties":{"type":"integer"},"type":"object","title":"Platform Quota","description":"How many posts each channel gets per batch, keyed by platform id. The batch is their sum. Zero (or absent) means the channel gets none; empty means the planner decides per post from cadence."},"brain_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Brain Id","description":"Ground posts in this Brain. None = the most recently updated."},"auto_approve":{"type":"boolean","title":"Auto Approve","description":"Schedule straight to the calendar instead of holding for review.","default":false}},"type":"object","title":"AutomationSettings","description":"When the agents plan, and when the posts they produce go out."},"BillingPlan":{"properties":{"tier":{"type":"string","title":"Tier"},"name":{"type":"string","title":"Name"},"section":{"type":"string","title":"Section"},"badge":{"type":"string","title":"Badge"},"support_label":{"type":"string","title":"Support Label"},"purchasable":{"type":"boolean","title":"Purchasable"},"price_monthly_usd_cents":{"type":"integer","title":"Price Monthly Usd Cents"},"price_yearly_usd_cents":{"type":"integer","title":"Price Yearly Usd Cents"},"annual_discount_percent":{"type":"integer","title":"Annual Discount Percent"},"included_credits":{"type":"integer","title":"Included Credits"},"channel_cap":{"type":"integer","title":"Channel Cap"},"x_account_cap":{"type":"integer","title":"X Account Cap"},"platform_account_caps":{"additionalProperties":{"type":"integer"},"type":"object","title":"Platform Account Caps"},"premium_action_cap":{"type":"integer","title":"Premium Action Cap"},"plan_run_cap":{"type":"integer","title":"Plan Run Cap"},"posts_per_plan_cap":{"type":"integer","title":"Posts Per Plan Cap"},"posts_per_write_cap":{"type":"integer","title":"Posts Per Write Cap","default":0},"total_ai_generation_cap":{"type":"integer","title":"Total Ai Generation Cap"},"non_x_scheduled_post_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Non X Scheduled Post Cap"},"seat_cap":{"type":"integer","title":"Seat Cap"},"workspace_cap":{"type":"integer","title":"Workspace Cap"},"ai_analytics_insight_cap":{"type":"integer","title":"Ai Analytics Insight Cap"},"automation_rule_cap":{"type":"integer","title":"Automation Rule Cap"},"x_posts_per_month_cap":{"type":"integer","title":"X Posts Per Month Cap"},"x_link_post_allowance_units":{"type":"integer","title":"X Link Post Allowance Units"},"x_analytics":{"type":"boolean","title":"X Analytics"},"x_analytics_snapshots_per_post":{"type":"integer","title":"X Analytics Snapshots Per Post"},"analytics_history_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Analytics History Days"},"analytics_refresh_interval_minutes":{"type":"integer","title":"Analytics Refresh Interval Minutes"},"brain_cap":{"type":"integer","title":"Brain Cap"},"brain_analysis_cap":{"type":"integer","title":"Brain Analysis Cap"},"brain_analysis_page_cap":{"type":"integer","title":"Brain Analysis Page Cap"},"lifetime_allowances":{"type":"boolean","title":"Lifetime Allowances"},"max_model_tier":{"type":"string","title":"Max Model Tier"},"critic_enabled":{"type":"boolean","title":"Critic Enabled"},"refine_enabled":{"type":"boolean","title":"Refine Enabled"},"mcp_enabled":{"type":"boolean","title":"Mcp Enabled"},"dodo_product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Product Id"},"dodo_yearly_product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Yearly Product Id"}},"type":"object","required":["tier","name","section","badge","support_label","purchasable","price_monthly_usd_cents","price_yearly_usd_cents","annual_discount_percent","included_credits","channel_cap","x_account_cap","premium_action_cap","plan_run_cap","posts_per_plan_cap","total_ai_generation_cap","non_x_scheduled_post_cap","seat_cap","workspace_cap","ai_analytics_insight_cap","automation_rule_cap","x_posts_per_month_cap","x_link_post_allowance_units","x_analytics","x_analytics_snapshots_per_post","analytics_history_days","analytics_refresh_interval_minutes","brain_cap","brain_analysis_cap","brain_analysis_page_cap","lifetime_allowances","max_model_tier","critic_enabled","refine_enabled","mcp_enabled","dodo_product_id","dodo_yearly_product_id"],"title":"BillingPlan","description":"The wire shape of one catalog plan.\n\nThis mirrors `app.billing.plans.Plan` field for field, and has to keep\ndoing so: the route builds it with `**plan.__dict__`, and `response_model`\nthen drops anything not declared here. A field the dataclass grew and this\nmodel never did is not a warning — it silently disappears from the payload,\nand the pricing page renders the bundled fallback copy for it.","example":{"ai_analytics_insight_cap":5,"annual_discount_percent":20,"automation_rule_cap":0,"channel_cap":5,"dodo_product_id":"prod_starter","dodo_yearly_product_id":"prod_starter_yearly","included_credits":0,"name":"Starter","plan_run_cap":0,"posts_per_plan_cap":7,"premium_action_cap":0,"price_monthly_usd_cents":1900,"price_yearly_usd_cents":18240,"seat_cap":1,"tier":"starter","total_ai_generation_cap":150,"x_account_cap":1,"x_posts_per_month_cap":40}},"BillingPlansResponse":{"properties":{"plans":{"items":{"$ref":"#/components/schemas/BillingPlan"},"type":"array","title":"Plans"},"topups":{"items":{"$ref":"#/components/schemas/TopUpOption"},"type":"array","title":"Topups"},"provider":{"type":"string","const":"dodo","title":"Provider"},"mode":{"type":"string","enum":["test","live"],"title":"Mode"},"action_costs":{"additionalProperties":{"type":"integer"},"type":"object","title":"Action Costs","default":{}}},"type":"object","required":["plans","topups","provider","mode"],"title":"BillingPlansResponse","example":{"mode":"test","plans":[{"ai_analytics_insight_cap":5,"annual_discount_percent":20,"automation_rule_cap":0,"channel_cap":5,"dodo_product_id":"prod_starter","dodo_yearly_product_id":"prod_starter_yearly","included_credits":0,"name":"Starter","plan_run_cap":0,"posts_per_plan_cap":7,"premium_action_cap":0,"price_monthly_usd_cents":1900,"price_yearly_usd_cents":18240,"seat_cap":1,"tier":"starter","total_ai_generation_cap":150,"x_account_cap":1}],"provider":"dodo","topups":[{"credits":500,"dodo_product_id":"prod_topup_500","price_usd":15}]}},"BillingPurchaseRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"payment_id":{"type":"string","title":"Payment Id"},"status":{"type":"string","title":"Status"},"kind":{"type":"string","title":"Kind"},"product_ids":{"items":{"type":"string"},"type":"array","title":"Product Ids"},"currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Currency"},"amount_minor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Amount Minor"},"paid_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Paid At"}},"type":"object","required":["id","workspace_id","payment_id","status","kind","product_ids","currency","amount_minor","paid_at"],"title":"BillingPurchaseRead"},"BlueskyConnectRequest":{"properties":{"identifier":{"type":"string","minLength":1,"title":"Identifier","description":"Bluesky handle or email.","examples":["cadencz.bsky.social"]},"app_password":{"type":"string","minLength":1,"title":"App Password","description":"Bluesky app password. Never send the account password.","examples":["abcd-efgh-ijkl-mnop"]}},"type":"object","required":["identifier","app_password"],"title":"BlueskyConnectRequest","example":{"app_password":"abcd-efgh-ijkl-mnop","identifier":"cadencz.bsky.social"}},"Body_upload_media_api_v1_media_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_media_api_v1_media_post"},"BootstrapResponse":{"properties":{"me":{"$ref":"#/components/schemas/CurrentUserResponse"},"preferences":{"anyOf":[{"$ref":"#/components/schemas/UserPreferences"},{"type":"null"}]},"channels":{"anyOf":[{"items":{"$ref":"#/components/schemas/ChannelRead"},"type":"array"},{"type":"null"}],"title":"Channels"},"subscription":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionRead"},{"type":"null"}]},"usage":{"anyOf":[{"$ref":"#/components/schemas/CreditUsageResponse"},{"type":"null"}]},"strategy":{"anyOf":[{"$ref":"#/components/schemas/StrategyRead"},{"type":"null"}]},"plan":{"anyOf":[{"$ref":"#/components/schemas/PlanRead"},{"type":"null"}]},"brains":{"anyOf":[{"items":{"$ref":"#/components/schemas/BrainRead"},"type":"array"},{"type":"null"}],"title":"Brains"},"media":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Media"},"failed":{"items":{"type":"string"},"type":"array","title":"Failed","default":[]}},"type":"object","required":["me"],"title":"BootstrapResponse","description":"Everything the app shell needs to render, in one round trip.\n\nEach field carries exactly the payload its own endpoint returns, so the\nclient can seed its cache key-for-key and never learns a second shape.\n\nA `null` section means one of two different things, and `failed` is what\ntells them apart: a name listed there could not be read and the client\nshould fetch that one endpoint itself, while a `null` that is *not* listed\nis a real absence (no content plan yet). Without that split, an outage in\none section would be indistinguishable from an empty workspace.","example":{"brains":[],"channels":[],"failed":[],"me":{"user":{"email":"creator@example.com","id":"CAD1234567890912","isAdmin":false,"name":"Creator","timezone":"Asia/Kolkata"},"workspace":{"handle":"workspace-wks_123","id":"wks_123","name":"Creator's Studio","ownerId":"CAD1234567890912"},"workspaces":[]},"media":[],"preferences":{"timezone":"Asia/Kolkata","weekStart":"monday"}}},"BrainChatRequest":{"properties":{"message":{"type":"string","maxLength":8000,"minLength":1,"title":"Message"},"mode":{"type":"string","enum":["auto","chat","create","refine"],"title":"Mode","default":"auto"},"platform":{"anyOf":[{"type":"string","maxLength":40,"minLength":1},{"type":"null"}],"title":"Platform"}},"type":"object","required":["message"],"title":"BrainChatRequest"},"BrainChatResponse":{"properties":{"conversation":{"$ref":"#/components/schemas/BrainConversationRead"},"user_message":{"$ref":"#/components/schemas/BrainMessageRead"},"assistant_message":{"$ref":"#/components/schemas/BrainMessageRead"},"intent":{"type":"string","enum":["chat","create","refine"],"title":"Intent"},"draft":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Draft"}},"type":"object","required":["conversation","user_message","assistant_message","intent","draft"],"title":"BrainChatResponse"},"BrainConversationCreate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":160},{"type":"null"}],"title":"Title"}},"type":"object","title":"BrainConversationCreate"},"BrainConversationDetail":{"properties":{"id":{"type":"string","title":"Id"},"brain_id":{"type":"string","title":"Brain Id"},"title":{"type":"string","title":"Title"},"status":{"type":"string","title":"Status"},"message_count":{"type":"integer","title":"Message Count"},"user_message_count":{"type":"integer","title":"User Message Count"},"current_draft":{"type":"string","title":"Current Draft"},"current_platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Platform"},"last_message_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Message At"},"summary_through_sequence":{"type":"integer","title":"Summary Through Sequence"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"summary":{"additionalProperties":true,"type":"object","title":"Summary"},"messages":{"items":{"$ref":"#/components/schemas/BrainMessageRead"},"type":"array","title":"Messages"}},"type":"object","required":["id","brain_id","title","status","message_count","user_message_count","current_draft","current_platform","last_message_at","summary_through_sequence","created_at","updated_at","summary"],"title":"BrainConversationDetail"},"BrainConversationHandoff":{"properties":{"kind":{"type":"string","const":"brain_conversation","title":"Kind","default":"brain_conversation"},"brain_id":{"type":"string","title":"Brain Id"},"conversation_id":{"type":"string","title":"Conversation Id"},"conversation_title":{"type":"string","title":"Conversation Title"},"message_id":{"type":"string","title":"Message Id"},"idea":{"type":"string","title":"Idea"},"platform":{"type":"string","title":"Platform"},"body":{"type":"string","title":"Body"},"agent_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Run Id"},"source_ids":{"items":{"type":"string"},"type":"array","title":"Source Ids"}},"type":"object","required":["brain_id","conversation_id","conversation_title","message_id","idea","platform","body","agent_run_id"],"title":"BrainConversationHandoff"},"BrainConversationRead":{"properties":{"id":{"type":"string","title":"Id"},"brain_id":{"type":"string","title":"Brain Id"},"title":{"type":"string","title":"Title"},"status":{"type":"string","title":"Status"},"message_count":{"type":"integer","title":"Message Count"},"user_message_count":{"type":"integer","title":"User Message Count"},"current_draft":{"type":"string","title":"Current Draft"},"current_platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Platform"},"last_message_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Message At"},"summary_through_sequence":{"type":"integer","title":"Summary Through Sequence"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","brain_id","title","status","message_count","user_message_count","current_draft","current_platform","last_message_at","summary_through_sequence","created_at","updated_at"],"title":"BrainConversationRead"},"BrainCreate":{"properties":{"name":{"type":"string","maxLength":160,"minLength":1,"title":"Name","examples":["Orbit CRM"]},"tagline":{"type":"string","maxLength":1000,"title":"Tagline","default":"","examples":["A calm CRM for founder-led sales teams."]},"emoji":{"type":"string","maxLength":16,"title":"Emoji","default":"*"},"accent":{"type":"string","maxLength":16,"title":"Accent","default":"#4338ca"}},"type":"object","required":["name"],"title":"BrainCreate"},"BrainMessageRead":{"properties":{"id":{"type":"string","title":"Id"},"conversation_id":{"type":"string","title":"Conversation Id"},"role":{"type":"string","enum":["user","assistant"],"title":"Role"},"sequence":{"type":"integer","title":"Sequence"},"content":{"type":"string","title":"Content"},"intent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent"},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider"},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model"},"agent_run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agent Run Id"},"metadata":{"additionalProperties":true,"type":"object","title":"Metadata"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","conversation_id","role","sequence","content","intent","provider","model","agent_run_id","metadata","created_at"],"title":"BrainMessageRead"},"BrainRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"name":{"type":"string","title":"Name"},"tagline":{"type":"string","title":"Tagline"},"emoji":{"type":"string","title":"Emoji"},"accent":{"type":"string","title":"Accent"},"source_count":{"type":"integer","title":"Source Count"},"fact_count":{"type":"integer","title":"Fact Count"},"site_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Site Url"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","workspace_id","name","tagline","emoji","accent","source_count","fact_count","updated_at","created_at"],"title":"BrainRead","example":{"accent":"#4338ca","created_at":"2026-07-08T10:00:00Z","emoji":"*","fact_count":14,"id":"brain_123","name":"Orbit CRM","source_count":2,"tagline":"A calm CRM for founder-led sales teams.","updated_at":"2026-07-08T10:30:00Z","workspace_id":"wks_123"}},"BrainSourceCreate":{"properties":{"kind":{"type":"string","maxLength":40,"minLength":1,"title":"Kind","examples":["text"]},"name":{"type":"string","maxLength":240,"minLength":1,"title":"Name","examples":["positioning-notes.txt"]},"detail":{"type":"string","maxLength":4000,"title":"Detail","default":"","examples":["TEXT - pasted notes"]},"excerpt":{"type":"string","maxLength":8000,"title":"Excerpt","default":"","examples":["Orbit helps founders remember follow-ups."]},"content":{"type":"string","maxLength":250000,"title":"Content","default":"","examples":["Full source text to ground generation."]}},"type":"object","required":["kind","name"],"title":"BrainSourceCreate"},"BrainSourceRead":{"properties":{"id":{"type":"string","title":"Id"},"brain_id":{"type":"string","title":"Brain Id"},"kind":{"type":"string","title":"Kind"},"name":{"type":"string","title":"Name"},"detail":{"type":"string","title":"Detail"},"status":{"type":"string","title":"Status"},"excerpt":{"type":"string","title":"Excerpt"},"content":{"type":"string","title":"Content"},"fact_count":{"type":"integer","title":"Fact Count"},"summary":{"type":"string","title":"Summary"},"summary_status":{"type":"string","enum":["ready","fallback","unavailable"],"title":"Summary Status"},"summary_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Provider"},"summary_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Summary Model"},"summary_updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Summary Updated At"},"added_at":{"type":"string","format":"date-time","title":"Added At"}},"type":"object","required":["id","brain_id","kind","name","detail","status","excerpt","content","fact_count","summary","summary_status","summary_provider","summary_model","summary_updated_at","added_at"],"title":"BrainSourceRead","example":{"added_at":"2026-07-08T10:30:00Z","brain_id":"brain_123","content":"Orbit helps founders remember follow-ups.","detail":"TEXT - pasted notes","excerpt":"Orbit helps founders remember follow-ups.","fact_count":3,"id":"src_123","kind":"text","name":"positioning-notes.txt","status":"indexed","summary":"Orbit is a CRM that helps founders remember sales follow-ups.","summary_model":"deepseek-v4-flash","summary_provider":"deepseek","summary_status":"ready","summary_updated_at":"2026-07-08T10:30:01Z"}},"BrainSourceUpdate":{"properties":{"name":{"type":"string","maxLength":240,"minLength":1,"title":"Name"},"detail":{"type":"string","maxLength":4000,"title":"Detail","default":""},"excerpt":{"type":"string","maxLength":8000,"title":"Excerpt","default":""},"content":{"type":"string","maxLength":250000,"title":"Content","default":""}},"type":"object","required":["name"],"title":"BrainSourceUpdate"},"BrandVoiceRead":{"properties":{"on_brand":{"type":"boolean","title":"On Brand","default":true},"confidence":{"type":"integer","title":"Confidence","default":0},"tone":{"type":"string","title":"Tone","default":""},"note":{"type":"string","title":"Note","default":""}},"type":"object","title":"BrandVoiceRead"},"CancelSubscriptionRequest":{"properties":{"feedback":{"anyOf":[{"type":"string","enum":["too_expensive","missing_features","switched_service","unused","customer_service","low_quality","too_complex","other"]},{"type":"null"}],"title":"Feedback"},"comment":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Comment"}},"type":"object","title":"CancelSubscriptionRequest","description":"Optional churn survey, passed through to Dodo's own cancellation fields."},"ChannelRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"platform":{"type":"string","title":"Platform"},"handle":{"type":"string","title":"Handle"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"status":{"type":"string","title":"Status"},"byo_app":{"type":"boolean","title":"Byo App"},"token_expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Token Expires At"},"followers":{"type":"integer","title":"Followers"},"capabilities":{"additionalProperties":true,"type":"object","title":"Capabilities"},"plan_entitled":{"type":"boolean","title":"Plan Entitled","default":true},"entitlement_status":{"type":"string","enum":["available","plan_paused","disconnected"],"title":"Entitlement Status","default":"available"},"plan_pause_reason":{"anyOf":[{"type":"string","enum":["plan_required","workspace_limit","platform_limit"]},{"type":"null"}],"title":"Plan Pause Reason"}},"type":"object","required":["id","workspace_id","platform","handle","display_name","avatar_url","status","byo_app","token_expires_at","followers"],"title":"ChannelRead","example":{"avatar_url":"https://example.com/avatar.png","byo_app":false,"display_name":"Cadencz","followers":42,"handle":"cadencz.bsky.social","id":"chn_123","platform":"bluesky","status":"connected","workspace_id":"wks_123"}},"CheckoutRequest":{"properties":{"tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tier"},"billing_period":{"type":"string","enum":["monthly","yearly"],"title":"Billing Period","default":"monthly"},"topup_credits":{"anyOf":[{"type":"integer","enum":[100,500]},{"type":"null"}],"title":"Topup Credits"},"return_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Return Url"},"cancel_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cancel Url"}},"type":"object","title":"CheckoutRequest","examples":[{"cancel_url":"http://localhost:3000/billing","return_url":"http://localhost:3000/billing/success","tier":"solo"},{"cancel_url":"http://localhost:3000/billing","return_url":"http://localhost:3000/billing/success","topup_credits":500}]},"CheckoutResponse":{"properties":{"action":{"type":"string","enum":["checkout","plan_change","unchanged","resumed","portal"],"title":"Action","default":"checkout"},"attempt_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Attempt Id"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"checkout_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Url"},"mode":{"type":"string","enum":["test","live"],"title":"Mode"},"client_secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Secret"},"payment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Id"},"publishable_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Publishable Key"},"effective_at":{"anyOf":[{"type":"string","enum":["immediately","next_billing_date"]},{"type":"null"}],"title":"Effective At"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"}},"type":"object","required":["checkout_url","mode"],"title":"CheckoutResponse","description":"One response for every way a plan click can resolve.\n\n`checkout` opens Dodo's hosted session; `plan_change` carries Dodo's\npayment page for the switch when money is due (`checkout_url` set), or\nreports an already-applied zero-charge change (`checkout_url` empty);\n`resumed` means a scheduled cancellation was lifted and nothing else\nneeded doing; `portal` sends the customer to Dodo's portal because the\nsubscription needs its payment method fixed there (`on_hold`/`paused`),\nwhich no API call of ours can do for them.","example":{"action":"checkout","checkout_url":"https://test.dodopayments.com/checkout/chk_123","mode":"test","session_id":"chk_123"}},"CompanyDocumentRead":{"properties":{"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"description":{"type":"string","title":"Description","default":""},"content":{"type":"string","title":"Content","default":""},"updated_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["slug","title"],"title":"CompanyDocumentRead"},"CompanyDocumentUpdate":{"properties":{"content":{"type":"string","maxLength":20000,"title":"Content","description":"Plain text; the UI enforces no markdown."}},"type":"object","required":["content"],"title":"CompanyDocumentUpdate"},"CompanyProfileData":{"properties":{"brand_name":{"type":"string","maxLength":120,"title":"Brand Name","default":""},"one_liner":{"type":"string","maxLength":300,"title":"One Liner","description":"One sentence: what it is, for whom.","default":""},"core_identity":{"type":"string","maxLength":600,"title":"Core Identity","default":""},"product_offering":{"type":"string","maxLength":750,"title":"Product Offering","default":""},"unique_benefits":{"items":{"type":"string"},"type":"array","maxItems":8,"title":"Unique Benefits"},"problem_solution":{"type":"string","maxLength":600,"title":"Problem Solution","default":""},"mission":{"type":"string","maxLength":450,"title":"Mission","default":""},"differentiation":{"type":"string","maxLength":600,"title":"Differentiation","default":""},"positioning":{"type":"string","maxLength":450,"title":"Positioning","default":""},"category":{"type":"string","maxLength":200,"title":"Category","default":""},"audience":{"type":"string","maxLength":600,"title":"Audience","default":""},"competitors":{"items":{"$ref":"#/components/schemas/CompetitorEntry"},"type":"array","maxItems":6,"title":"Competitors"},"tone":{"type":"string","maxLength":450,"title":"Tone","description":"How the site sounds, in plain language.","default":""},"business_model":{"type":"string","maxLength":600,"title":"Business Model","default":""},"primary_cta":{"type":"string","maxLength":200,"title":"Primary Cta","default":""},"content_angles":{"items":{"$ref":"#/components/schemas/ContentAngle"},"type":"array","maxItems":5,"title":"Content Angles"},"pricing_notes":{"type":"string","maxLength":450,"title":"Pricing Notes","default":""}},"type":"object","title":"CompanyProfileData","description":"The structured company knowledge shown in the /today company panel.\n\nSections mirror the product spec: Identity & Product, Purpose & Positioning,\nMarket & Competition. Every field is plain prose the user can edit."},"CompanyProfileRead":{"properties":{"id":{"type":"string","title":"Id"},"source_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Url"},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id"},"status":{"type":"string","title":"Status"},"profile":{"$ref":"#/components/schemas/CompanyProfileData"},"documents":{"items":{"$ref":"#/components/schemas/CompanyDocumentRead"},"type":"array","title":"Documents"},"audit":{"additionalProperties":true,"type":"object","title":"Audit"},"month_plan":{"additionalProperties":true,"type":"object","title":"Month Plan"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","status","profile","updated_at"],"title":"CompanyProfileRead"},"CompanyProfileUpdate":{"properties":{"profile":{"$ref":"#/components/schemas/CompanyProfileData"}},"type":"object","required":["profile"],"title":"CompanyProfileUpdate","description":"Full replace of the structured profile — the panel edits it as one form."},"CompetitorEntry":{"properties":{"name":{"type":"string","maxLength":80,"title":"Name"},"positioning":{"type":"string","maxLength":220,"title":"Positioning","description":"How they position themselves.","default":""},"gap":{"type":"string","maxLength":300,"title":"Gap","description":"Where this company wins against them.","default":""}},"type":"object","required":["name"],"title":"CompetitorEntry"},"ConsentDescribeResponse":{"properties":{"client_name":{"type":"string","title":"Client Name"},"redirect_host":{"type":"string","title":"Redirect Host"}},"type":"object","required":["client_name","redirect_host"],"title":"ConsentDescribeResponse"},"ConsentRequest":{"properties":{"request":{"type":"string","maxLength":8000,"minLength":10,"title":"Request"},"approve":{"type":"boolean","title":"Approve"}},"type":"object","required":["request","approve"],"title":"ConsentRequest"},"ConsentResponse":{"properties":{"redirect_url":{"type":"string","title":"Redirect Url"}},"type":"object","required":["redirect_url"],"title":"ConsentResponse"},"ContentAngle":{"properties":{"title":{"type":"string","maxLength":80,"title":"Title"},"rationale":{"type":"string","maxLength":220,"title":"Rationale","default":""}},"type":"object","required":["title"],"title":"ContentAngle"},"CreditBalanceResponse":{"properties":{"balance":{"type":"integer","title":"Balance"}},"type":"object","required":["balance"],"title":"CreditBalanceResponse"},"CreditCategoryUsageRead":{"properties":{"reason":{"type":"string","title":"Reason"},"label":{"type":"string","title":"Label"},"granted":{"type":"integer","title":"Granted"},"used":{"type":"integer","title":"Used"},"balance":{"type":"integer","title":"Balance"},"cost_usd_micros":{"type":"integer","title":"Cost Usd Micros"}},"type":"object","required":["reason","label","granted","used","balance","cost_usd_micros"],"title":"CreditCategoryUsageRead"},"CreditLedgerEntryRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id"},"at":{"type":"string","title":"At"},"delta":{"type":"integer","title":"Delta"},"balance_after":{"type":"integer","title":"Balance After"},"reason":{"type":"string","title":"Reason"},"note":{"type":"string","title":"Note"},"external_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Ref"}},"type":"object","required":["id","workspace_id","user_id","brain_id","at","delta","balance_after","reason","note","external_ref"],"title":"CreditLedgerEntryRead","example":{"at":"2026-07-08T10:30:00Z","balance_after":299,"brain_id":"brain_123","delta":-1,"id":"led_123","note":"Generated linkedin draft","reason":"text_draft","user_id":"CAD1234567890912","workspace_id":"wks_123"}},"CreditProjectUsageRead":{"properties":{"project_id":{"type":"string","title":"Project Id"},"project_type":{"type":"string","enum":["workspace","brain"],"title":"Project Type"},"name":{"type":"string","title":"Name"},"workspace_id":{"type":"string","title":"Workspace Id"},"granted":{"type":"integer","title":"Granted"},"used":{"type":"integer","title":"Used"},"balance":{"type":"integer","title":"Balance"},"cost_usd_micros":{"type":"integer","title":"Cost Usd Micros"}},"type":"object","required":["project_id","project_type","name","workspace_id","granted","used","balance","cost_usd_micros"],"title":"CreditProjectUsageRead"},"CreditUsageResponse":{"properties":{"user_id":{"type":"string","title":"User Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"balance":{"type":"integer","title":"Balance"},"granted":{"type":"integer","title":"Granted"},"used":{"type":"integer","title":"Used"},"workspace_balance":{"type":"integer","title":"Workspace Balance"},"workspace_granted":{"type":"integer","title":"Workspace Granted"},"workspace_used":{"type":"integer","title":"Workspace Used"},"cost_usd_micros":{"type":"integer","title":"Cost Usd Micros"},"workspace_cost_usd_micros":{"type":"integer","title":"Workspace Cost Usd Micros"},"categories":{"items":{"$ref":"#/components/schemas/CreditCategoryUsageRead"},"type":"array","title":"Categories"},"projects":{"items":{"$ref":"#/components/schemas/CreditProjectUsageRead"},"type":"array","title":"Projects"}},"type":"object","required":["user_id","workspace_id","balance","granted","used","workspace_balance","workspace_granted","workspace_used","cost_usd_micros","workspace_cost_usd_micros","categories","projects"],"title":"CreditUsageResponse","example":{"balance":348,"categories":[{"balance":-2,"cost_usd_micros":1200,"granted":0,"label":"Brain compose","reason":"text_draft","used":2}],"cost_usd_micros":1200,"granted":350,"projects":[{"balance":-2,"cost_usd_micros":1200,"granted":0,"name":"Orbit CRM","project_id":"brain_123","project_type":"brain","used":2,"workspace_id":"wks_123"}],"used":2,"user_id":"CAD1234567890912","workspace_balance":348,"workspace_cost_usd_micros":1200,"workspace_granted":350,"workspace_id":"wks_123","workspace_used":2}},"CriticalBootstrapResponse":{"properties":{"me":{"$ref":"#/components/schemas/CurrentUserResponse"},"subscription":{"anyOf":[{"$ref":"#/components/schemas/SubscriptionRead"},{"type":"null"}]},"failed":{"items":{"type":"string"},"type":"array","title":"Failed","default":[]}},"type":"object","required":["me"],"title":"CriticalBootstrapResponse","description":"The two reads that decide whether the authenticated shell may render."},"CurrentUserProfile":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"name":{"type":"string","title":"Name"},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatarurl"},"timezone":{"type":"string","title":"Timezone"},"isAdmin":{"type":"boolean","title":"Isadmin","default":false},"createdAt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Createdat"}},"type":"object","required":["id","email","name","avatarUrl","timezone"],"title":"CurrentUserProfile"},"CurrentUserResponse":{"properties":{"user":{"$ref":"#/components/schemas/CurrentUserProfile"},"workspace":{"$ref":"#/components/schemas/CurrentWorkspaceProfile"},"workspaces":{"items":{"$ref":"#/components/schemas/CurrentWorkspaceProfile"},"type":"array","title":"Workspaces"},"role":{"type":"string","title":"Role","default":"owner"},"accountId":{"type":"string","title":"Accountid","default":""},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions","default":[]},"workspaceCap":{"type":"integer","title":"Workspacecap","default":1},"setupComplete":{"type":"boolean","title":"Setupcomplete","default":true}},"type":"object","required":["user","workspace","workspaces"],"title":"CurrentUserResponse"},"CurrentWorkspaceProfile":{"properties":{"id":{"type":"string","title":"Id"},"ownerId":{"type":"string","title":"Ownerid"},"name":{"type":"string","title":"Name"},"handle":{"type":"string","title":"Handle"},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatarurl"}},"type":"object","required":["id","ownerId","name","handle","avatarUrl"],"title":"CurrentWorkspaceProfile"},"DeferredBootstrapResponse":{"properties":{"preferences":{"anyOf":[{"$ref":"#/components/schemas/UserPreferences"},{"type":"null"}]},"channels":{"anyOf":[{"items":{"$ref":"#/components/schemas/ChannelRead"},"type":"array"},{"type":"null"}],"title":"Channels"},"usage":{"anyOf":[{"$ref":"#/components/schemas/CreditUsageResponse"},{"type":"null"}]},"strategy":{"anyOf":[{"$ref":"#/components/schemas/StrategyRead"},{"type":"null"}]},"plan":{"anyOf":[{"$ref":"#/components/schemas/PlanRead"},{"type":"null"}]},"brains":{"anyOf":[{"items":{"$ref":"#/components/schemas/BrainRead"},"type":"array"},{"type":"null"}],"title":"Brains"},"media":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Media"},"failed":{"items":{"type":"string"},"type":"array","title":"Failed","default":[]}},"type":"object","title":"DeferredBootstrapResponse","description":"Workspace data warmed after the shell's critical path has completed."},"DevToConnectRequest":{"properties":{"api_key":{"type":"string","title":"Api Key","description":"dev.to API key.","examples":["abcd1234..."]},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name","description":"Optional label for the channel."}},"type":"object","required":["api_key"],"title":"DevToConnectRequest","description":"Connect dev.to by pasting the API key from Settings → Extensions."},"DodoWebhookResponse":{"properties":{"status":{"type":"string","enum":["ok","duplicate"],"title":"Status"}},"type":"object","required":["status"],"title":"DodoWebhookResponse","example":{"status":"ok"}},"DraftInput":{"properties":{"client_id":{"type":"string","format":"uuid","title":"Client Id"},"tool_slug":{"type":"string","maxLength":100,"title":"Tool Slug"},"body":{"type":"string","maxLength":16000,"minLength":1,"title":"Body"}},"type":"object","required":["client_id","tool_slug","body"],"title":"DraftInput"},"ErrorResponse":{"properties":{"detail":{"anyOf":[{"type":"string"},{"additionalProperties":true,"type":"object"},{"items":{},"type":"array"}],"title":"Detail"}},"type":"object","required":["detail"],"title":"ErrorResponse","example":{"detail":"Authorization header is required."}},"GeneratedPlatformText":{"properties":{"platform":{"type":"string","title":"Platform"},"text":{"type":"string","title":"Text"},"provider":{"type":"string","title":"Provider"},"model":{"type":"string","title":"Model"},"agent_run_id":{"type":"string","title":"Agent Run Id"},"draft_index":{"type":"integer","minimum":1.0,"title":"Draft Index","default":1}},"type":"object","required":["platform","text","provider","model","agent_run_id"],"title":"GeneratedPlatformText","example":{"agent_run_id":"run_123","model":"gpt-5.4-mini","platform":"twitter","provider":"openai","text":"Google sign-in is now live, with backend token checks doing the heavy lifting."}},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HealthResponse":{"properties":{"status":{"type":"string","title":"Status"},"service":{"type":"string","title":"Service"}},"type":"object","required":["status","service"],"title":"HealthResponse","example":{"service":"cadencz-backend","status":"ok"}},"IdeasRequest":{"properties":{"seed":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Seed","description":"Optional focus/topic for this batch. Omit to ideate from the workspace strategy.","examples":["onboarding and activation"]},"count":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Count","description":"How many ideas to generate.","default":8}},"type":"object","title":"IdeasRequest","example":{"count":8,"seed":"pricing lessons"}},"IdeasResponse":{"properties":{"ideas":{"items":{"$ref":"#/components/schemas/PostIdeaRead"},"type":"array","title":"Ideas"}},"type":"object","required":["ideas"],"title":"IdeasResponse","example":{"ideas":[{"angle":"contrarian","hook":"We cut onboarding from 6 steps to 2. Activation went up, not down.","pillar":"build-in-public","platform":"x","theme":"The onboarding step we deleted","why":"Concrete result tied to the activation pillar."}]}},"InviteAcceptResponse":{"properties":{"accountId":{"type":"string","title":"Accountid"},"workspaceId":{"type":"string","title":"Workspaceid"},"role":{"type":"string","title":"Role"}},"type":"object","required":["accountId","workspaceId","role"],"title":"InviteAcceptResponse","example":{"user":{"avatarUrl":"https://example.com/avatar.png","email":"creator@example.com","id":"CAD1234567890912","isAdmin":false,"name":"Creator","timezone":"UTC"},"workspace":{"handle":"creator","id":"wks_123","name":"Creator's Workspace","ownerId":"CAD1234567890912"},"workspaces":[]}},"InviteCreateRequest":{"properties":{"email":{"type":"string","title":"Email"},"role":{"type":"string","title":"Role","default":"scheduler"},"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions","default":[]}},"type":"object","required":["email"],"title":"InviteCreateRequest"},"InvitePreviewResponse":{"properties":{"accountName":{"type":"string","title":"Accountname"},"invitedBy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invitedby"},"role":{"type":"string","title":"Role"},"email":{"type":"string","title":"Email"},"status":{"type":"string","title":"Status"},"expiresAt":{"type":"string","title":"Expiresat"}},"type":"object","required":["accountName","role","email","status","expiresAt"],"title":"InvitePreviewResponse","description":"What the invite landing page may say before anyone has signed in.\n\nUnauthenticated — the token is the credential. The address is masked: a\nforwarded link should let the holder check which mailbox this was for\nwithout handing a stranger a working address."},"LearnVoiceRequest":{"properties":{"posts":{"items":{"type":"string"},"type":"array","maxItems":20,"minItems":1,"title":"Posts","description":"5-10 of the user's past posts. The voice agent learns their tone from these."},"niche":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Niche"},"writing_notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Writing Notes"},"avoid_style":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Avoid Style"},"platform":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Platform","description":"The platform these posts were written for (x, linkedin, threads, …). The tone learned from them is then used for that platform's drafts only. Omit for posts that stand for every platform."}},"type":"object","required":["posts"],"title":"LearnVoiceRequest"},"LearnVoiceResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"voice":{"additionalProperties":true,"type":"object","title":"Voice"},"strategy":{"$ref":"#/components/schemas/StrategyRead"}},"type":"object","required":["run_id","voice","strategy"],"title":"LearnVoiceResponse"},"MastodonOAuthStartRequest":{"properties":{"instance_url":{"type":"string","minLength":1,"title":"Instance Url","description":"The Mastodon instance to connect (host or URL).","examples":["mastodon.social"]}},"type":"object","required":["instance_url"],"title":"MastodonOAuthStartRequest"},"MediaRead":{"properties":{"id":{"type":"string","title":"Id"},"kind":{"type":"string","title":"Kind"},"url":{"type":"string","title":"Url"},"alt_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Alt Text"},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Width"},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Height"},"bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bytes"}},"type":"object","required":["id","kind","url"],"title":"MediaRead"},"MemberUpdateRequest":{"properties":{"permissions":{"items":{"type":"string"},"type":"array","title":"Permissions"}},"type":"object","required":["permissions"],"title":"MemberUpdateRequest","description":"What an owner may change about someone else's seat. Role is deliberately\nabsent: promoting someone to owner is an account transfer, not a toggle."},"ModelRunRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"at":{"type":"string","title":"At"},"provider":{"type":"string","title":"Provider"},"model":{"type":"string","title":"Model"},"task":{"type":"string","title":"Task"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"},"total_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Tokens"},"cached_input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cached Input Tokens"},"cache_write_5m_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cache Write 5M Tokens"},"cache_write_1h_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cache Write 1H Tokens"},"reasoning_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reasoning Tokens"},"input_cost_usd_micros":{"type":"integer","title":"Input Cost Usd Micros"},"output_cost_usd_micros":{"type":"integer","title":"Output Cost Usd Micros"},"cost_usd_micros":{"type":"integer","title":"Cost Usd Micros"},"pricing_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pricing Source"}},"type":"object","required":["id","workspace_id","at","provider","model","task","input_tokens","output_tokens","total_tokens","cached_input_tokens","cache_write_5m_tokens","cache_write_1h_tokens","reasoning_tokens","input_cost_usd_micros","output_cost_usd_micros","cost_usd_micros","pricing_source"],"title":"ModelRunRead"},"MonthReplanJobResponse":{"properties":{"status":{"type":"string","title":"Status"},"checked":{"type":"integer","title":"Checked"},"replanned":{"type":"integer","title":"Replanned"},"skipped":{"type":"integer","title":"Skipped"},"failed":{"type":"integer","title":"Failed"}},"type":"object","required":["status","checked","replanned","skipped","failed"],"title":"MonthReplanJobResponse"},"OAuthStartRequest":{"properties":{"learn_voice":{"type":"boolean","title":"Learn Voice","description":"After the account connects, read its ten most recent posts once and save them as writing samples on the Writing style page. X only — LinkedIn does not let an app read a member's posts.","default":false}},"type":"object","title":"OAuthStartRequest","description":"Options that ride the OAuth round-trip in the signed state."},"OAuthStartResponse":{"properties":{"authorization_url":{"type":"string","title":"Authorization Url","description":"Provider OAuth approval URL."}},"type":"object","required":["authorization_url"],"title":"OAuthStartResponse","description":"Returned by any provider's OAuth start endpoint; the frontend redirects\nthe browser to `authorization_url`."},"OnboardingRunRead":{"properties":{"id":{"type":"string","title":"Id"},"source_kind":{"type":"string","title":"Source Kind","default":"url"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"status":{"type":"string","title":"Status"},"current_step":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Step"},"steps":{"items":{"$ref":"#/components/schemas/OnboardingStepRead"},"type":"array","title":"Steps"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id"},"content_plan_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Plan Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"finished_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Finished At"}},"type":"object","required":["id","status","created_at"],"title":"OnboardingRunRead"},"OnboardingStartRequest":{"properties":{"url":{"anyOf":[{"type":"string","maxLength":2000,"minLength":4},{"type":"null"}],"title":"Url","description":"The website to analyze."},"brief":{"anyOf":[{"type":"string","maxLength":50000},{"type":"null"}],"title":"Brief","description":"A written description of the product, used instead of a website: what it is, who it is for, the problem, the benefits, the tone."},"company_name":{"anyOf":[{"type":"string","maxLength":160},{"type":"null"}],"title":"Company Name","description":"The brand or product name. Required with a brief."},"platforms":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":20},{"type":"null"}],"title":"Platforms","description":"Where the first week should be written for. Saved to the strategy before the run starts."},"goals":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":12},{"type":"null"}],"title":"Goals","description":"What the posts are for — ids from the goal catalogue (promote, learnings, engage, build_in_public, grow, authority). Saved to the strategy before the run."},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id","description":"Target an existing brain."},"new_brain":{"type":"boolean","title":"New Brain","description":"Force a fresh brain (plan-capped).","default":false},"refresh":{"type":"boolean","title":"Refresh","description":"Re-read the brain's data only — its plan is left untouched.","default":false}},"type":"object","title":"OnboardingStartRequest"},"OnboardingStepRead":{"properties":{"key":{"type":"string","title":"Key"},"label":{"type":"string","title":"Label"},"status":{"type":"string","title":"Status"},"detail":{"type":"string","title":"Detail","default":""},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"finished_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Finished At"}},"type":"object","required":["key","label","status"],"title":"OnboardingStepRead"},"PendingInviteRead":{"properties":{"id":{"type":"string","title":"Id"},"accountName":{"type":"string","title":"Accountname"},"invitedBy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Invitedby"},"role":{"type":"string","title":"Role"},"expiresAt":{"type":"string","title":"Expiresat"}},"type":"object","required":["id","accountName","role","expiresAt"],"title":"PendingInviteRead","description":"An invite waiting for the signed-in person. Addressed to them and they\nare authenticated, so nothing is masked — unlike the public link preview."},"PlanAllowanceRead":{"properties":{"tier":{"type":"string","title":"Tier"},"period_start":{"type":"string","title":"Period Start"},"premium_actions_used":{"type":"integer","title":"Premium Actions Used"},"premium_actions_cap":{"type":"integer","title":"Premium Actions Cap"},"plan_runs_used":{"type":"integer","title":"Plan Runs Used"},"plan_runs_cap":{"type":"integer","title":"Plan Runs Cap"},"posts_per_plan_cap":{"type":"integer","title":"Posts Per Plan Cap"},"weekly_posts_used":{"type":"integer","title":"Weekly Posts Used","default":0},"weekly_posts_cap":{"type":"integer","title":"Weekly Posts Cap","default":0},"weekly_posts_per_write":{"type":"integer","title":"Weekly Posts Per Write","default":0},"week_resets_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Week Resets At"},"x_weekly_posts_used":{"type":"integer","title":"X Weekly Posts Used","default":0},"x_weekly_posts_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"X Weekly Posts Cap"},"total_ai_generations_used":{"type":"integer","title":"Total Ai Generations Used"},"total_ai_generations_cap":{"type":"integer","title":"Total Ai Generations Cap"},"brain_refreshes_used":{"type":"integer","title":"Brain Refreshes Used","default":0},"brain_refreshes_cap":{"type":"integer","title":"Brain Refreshes Cap","default":0},"brain_refreshes_monthly":{"type":"boolean","title":"Brain Refreshes Monthly","default":true},"ai_analytics_insights_used":{"type":"integer","title":"Ai Analytics Insights Used"},"ai_analytics_insights_cap":{"type":"integer","title":"Ai Analytics Insights Cap"},"x_posts_cap":{"type":"integer","title":"X Posts Cap"},"non_x_scheduled_posts_cap":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Non X Scheduled Posts Cap"},"channel_cap":{"type":"integer","title":"Channel Cap"},"x_account_cap":{"type":"integer","title":"X Account Cap"},"platform_account_caps":{"additionalProperties":{"type":"integer"},"type":"object","title":"Platform Account Caps"},"seat_cap":{"type":"integer","title":"Seat Cap"},"automation_rule_cap":{"type":"integer","title":"Automation Rule Cap"}},"type":"object","required":["tier","period_start","premium_actions_used","premium_actions_cap","plan_runs_used","plan_runs_cap","posts_per_plan_cap","total_ai_generations_used","total_ai_generations_cap","ai_analytics_insights_used","ai_analytics_insights_cap","x_posts_cap","non_x_scheduled_posts_cap","channel_cap","x_account_cap","seat_cap","automation_rule_cap"],"title":"PlanAllowanceRead"},"PlanChangePreviewRead":{"properties":{"tier":{"type":"string","title":"Tier"},"tier_name":{"type":"string","title":"Tier Name"},"billing_period":{"type":"string","enum":["monthly","yearly"],"title":"Billing Period"},"effective_at":{"type":"string","enum":["immediately","next_billing_date"],"title":"Effective At"},"charges_today":{"type":"boolean","title":"Charges Today"},"immediate_total_minor":{"type":"integer","title":"Immediate Total Minor"},"currency":{"type":"string","title":"Currency"},"tax_minor":{"type":"integer","title":"Tax Minor"},"customer_credits_minor":{"type":"integer","title":"Customer Credits Minor"},"recurring_pre_tax_minor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Recurring Pre Tax Minor"},"recurring_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurring Currency"},"next_billing_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Billing Date"},"needs_resume":{"type":"boolean","title":"Needs Resume","default":false},"resumes_current_plan":{"type":"boolean","title":"Resumes Current Plan","default":false},"needs_fresh_checkout":{"type":"boolean","title":"Needs Fresh Checkout","default":false},"needs_payment_fix":{"type":"boolean","title":"Needs Payment Fix","default":false}},"type":"object","required":["tier","tier_name","billing_period","effective_at","charges_today","immediate_total_minor","currency","tax_minor","customer_credits_minor","recurring_pre_tax_minor","recurring_currency","next_billing_date"],"title":"PlanChangePreviewRead","description":"Dodo's own quote for a switch, shown before the customer authorises it.\n\nAmounts are provider minor units in `currency`. When `needs_resume` is set\nthere are no amounts to show: Dodo will not quote a subscription that is on\nits way out, so the switch resumes it first and the figures then come from\nDodo's own payment page.","example":{"billing_period":"monthly","charges_today":true,"currency":"USD","customer_credits_minor":0,"effective_at":"immediately","immediate_total_minor":1320,"next_billing_date":"2026-09-23T10:30:00Z","recurring_currency":"USD","recurring_pre_tax_minor":3900,"tax_minor":0,"tier":"founder","tier_name":"Founder"}},"PlanChangePreviewRequest":{"properties":{"tier":{"type":"string","title":"Tier"},"billing_period":{"type":"string","enum":["monthly","yearly"],"title":"Billing Period","default":"monthly"}},"type":"object","required":["tier"],"title":"PlanChangePreviewRequest"},"PlanGenerateRequest":{"properties":{"fresh":{"type":"boolean","title":"Fresh","default":false}},"type":"object","title":"PlanGenerateRequest"},"PlanItemApproveRequest":{"properties":{"scheduled_for":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled For"},"asap":{"type":"boolean","title":"Asap","default":false},"as_draft":{"type":"boolean","title":"As Draft","default":false}},"type":"object","title":"PlanItemApproveRequest","description":"When the post goes out. Nothing set = the planner's slot (rolled\nforward if it has passed); `asap` = a few minutes from now; a\n`scheduled_for` = exactly then."},"PlanItemRead":{"properties":{"id":{"type":"string","title":"Id"},"theme":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Theme"},"angle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Angle"},"platforms":{"items":{"type":"string"},"type":"array","title":"Platforms"},"why":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Why"},"prompt":{"type":"string","title":"Prompt"},"scheduled_for":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled For"},"status":{"type":"string","title":"Status"},"format":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Format"},"publish_mode":{"type":"string","title":"Publish Mode","default":"single"},"content_metadata":{"additionalProperties":true,"type":"object","title":"Content Metadata"},"body_parts":{"items":{"type":"string"},"type":"array","title":"Body Parts"},"media_ids":{"items":{"type":"string"},"type":"array","title":"Media Ids"},"media":{"items":{"$ref":"#/components/schemas/MediaRead"},"type":"array","title":"Media"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","theme","angle","platforms","why","prompt","scheduled_for","status"],"title":"PlanItemRead"},"PlanItemRefineRequest":{"properties":{"feedback":{"type":"string","maxLength":1000,"minLength":3,"title":"Feedback"}},"type":"object","required":["feedback"],"title":"PlanItemRefineRequest"},"PlanItemRefineResponse":{"properties":{"item":{"$ref":"#/components/schemas/PlanItemRead"},"message":{"type":"string","title":"Message"}},"type":"object","required":["item","message"],"title":"PlanItemRefineResponse"},"PlanItemUpdate":{"properties":{"theme":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Theme"},"angle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Angle"},"prompt":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt"},"platforms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Platforms"},"scheduled_for":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled For"},"publish_mode":{"anyOf":[{"type":"string","enum":["single","long_form","thread"]},{"type":"null"}],"title":"Publish Mode"},"body_parts":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Body Parts"},"media_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Media Ids"},"decision":{"anyOf":[{"type":"string","enum":["accepted","rejected",""]},{"type":"null"}],"title":"Decision"}},"type":"object","title":"PlanItemUpdate"},"PlanRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"week_of":{"type":"string","format":"date-time","title":"Week Of"},"goal":{"type":"string","title":"Goal"},"niche":{"type":"string","title":"Niche"},"status":{"type":"string","title":"Status"},"items":{"items":{"$ref":"#/components/schemas/PlanItemRead"},"type":"array","title":"Items"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","workspace_id","week_of","goal","niche","status","items","created_at"],"title":"PlanRead","example":{"created_at":"2026-07-13T10:00:00Z","goal":"grow","id":"plan_123","items":[{"angle":"reframe reliability as a principle","id":"item_1","platforms":["x"],"prompt":"Write about the single rule that governs our tradeoffs.","scheduled_for":"2026-07-14T09:00:00Z","status":"draft","theme":"The one-rule philosophy","why":"Tue mornings get 2x engagement for you."}],"niche":"indie SaaS","status":"draft","week_of":"2026-07-13T00:00:00Z","workspace_id":"wks_123"}},"PlanStackRead":{"properties":{"items":{"items":{"$ref":"#/components/schemas/PlanItemRead"},"type":"array","title":"Items"}},"type":"object","required":["items"],"title":"PlanStackRead","description":"Every post still waiting on a verdict, across weeks — the stack."},"PlanWeekJobResponse":{"properties":{"status":{"type":"string","const":"ok","title":"Status"},"workspaces":{"type":"integer","title":"Workspaces"},"planned":{"type":"integer","title":"Planned"},"skipped":{"type":"integer","title":"Skipped"},"failed":{"type":"integer","title":"Failed"}},"type":"object","required":["status","workspaces","planned","skipped","failed"],"title":"PlanWeekJobResponse","example":{"failed":0,"planned":4,"skipped":8,"status":"ok","workspaces":12}},"PortalRequest":{"properties":{"return_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Return Url","examples":["http://localhost:3000/billing"]}},"type":"object","title":"PortalRequest","example":{"return_url":"http://localhost:3000/billing"}},"PortalResponse":{"properties":{"link":{"type":"string","title":"Link"}},"type":"object","required":["link"],"title":"PortalResponse","example":{"link":"https://test.dodopayments.com/customer-portal/session_123"}},"PostCounts":{"properties":{"awaiting_review":{"type":"integer","title":"Awaiting Review","default":0}},"type":"object","title":"PostCounts","description":"Small shell payload for badges that do not need complete post bodies."},"PostCreate":{"properties":{"idea":{"type":"string","minLength":1,"title":"Idea","examples":["Turn this product changelog into a Bluesky post."]},"source":{"type":"string","enum":["manual","agent"],"title":"Source","default":"manual"},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id","examples":["brain_123"]},"timezone":{"type":"string","title":"Timezone","description":"IANA zone the schedule times were chosen in. `scheduled_at` is already absolute, so this does not move the post — it records what the customer meant, which is what a later reschedule or a best-time read has to honour.","default":"UTC","examples":["Asia/Kolkata"]},"variants":{"items":{"$ref":"#/components/schemas/VariantCreate"},"type":"array","title":"Variants"}},"type":"object","required":["idea"],"title":"PostCreate","example":{"brain_id":"brain_123","idea":"Turn this product changelog into a Bluesky post.","source":"manual","variants":[{"body":"Cadencz now supports scheduled Bluesky posts.","channel_id":"chn_123","media_ids":[],"platform":"bluesky","scheduled_at":"2026-07-08T10:30:00Z"}]}},"PostIdeaRead":{"properties":{"theme":{"type":"string","title":"Theme"},"angle":{"type":"string","title":"Angle","default":""},"hook":{"type":"string","title":"Hook","default":""},"platform":{"type":"string","title":"Platform","default":""},"pillar":{"type":"string","title":"Pillar","default":""},"why":{"type":"string","title":"Why","default":""}},"type":"object","required":["theme"],"title":"PostIdeaRead"},"PostRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"idea":{"type":"string","title":"Idea"},"source":{"type":"string","title":"Source"},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id"},"variants":{"items":{"$ref":"#/components/schemas/VariantRead"},"type":"array","title":"Variants"}},"type":"object","required":["id","workspace_id","idea","source","brain_id"],"title":"PostRead","example":{"brain_id":"brain_123","id":"pst_123","idea":"Turn this product changelog into a Bluesky post.","source":"manual","variants":[{"attempt_count":0,"body":"Cadencz now supports scheduled Bluesky posts.","channel_id":"chn_123","id":"var_123","media_ids":[],"platform":"bluesky","post_id":"pst_123","scheduled_at":"2026-07-08T10:30:00Z","status":"scheduled"}],"workspace_id":"wks_123"}},"PostReviewResponse":{"properties":{"suggestions":{"items":{"$ref":"#/components/schemas/PostSuggestionRead"},"type":"array","title":"Suggestions","default":[]},"brand_voice":{"$ref":"#/components/schemas/BrandVoiceRead","default":{"on_brand":true,"confidence":0,"tone":"","note":""}},"voice_source":{"type":"string","title":"Voice Source","default":"neutral_product"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"}},"type":"object","title":"PostReviewResponse","example":{"brand_voice":{"confidence":94,"note":"Matches your direct, build-in-public voice.","on_brand":true,"tone":"Confident, plain"},"suggestions":[{"detail":"Open with the surprising result, not the setup.","revised_body":"We cut onboarding to 2 steps and activation rose 18%…","title":"Stronger hook"}]}},"PostSuggestionRead":{"properties":{"title":{"type":"string","title":"Title"},"detail":{"type":"string","title":"Detail","default":""},"revised_body":{"type":"string","title":"Revised Body","default":""}},"type":"object","required":["title"],"title":"PostSuggestionRead"},"PromoteInput":{"properties":{"channel_id":{"type":"string","maxLength":36,"title":"Channel Id"},"body":{"type":"string","maxLength":16000,"minLength":1,"title":"Body"}},"type":"object","required":["channel_id","body"],"title":"PromoteInput"},"PublishDueJobResponse":{"properties":{"status":{"type":"string","const":"ok","title":"Status"},"checked":{"type":"integer","title":"Checked"},"claimed":{"type":"integer","title":"Claimed"},"published":{"type":"integer","title":"Published"},"failed":{"type":"integer","title":"Failed"},"retryable":{"type":"integer","title":"Retryable"},"skipped":{"type":"integer","title":"Skipped"}},"type":"object","required":["status","checked","claimed","published","failed","retryable","skipped"],"title":"PublishDueJobResponse","example":{"checked":3,"claimed":3,"failed":0,"published":2,"retryable":1,"skipped":0,"status":"ok"}},"PublishedPageRead":{"properties":{"items":{"items":{"$ref":"#/components/schemas/VariantRead"},"type":"array","title":"Items"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","title":"PublishedPageRead","description":"A page of what has gone out, newest first, and where the next page starts."},"RedditOAuthStartResponse":{"properties":{"authorization_url":{"type":"string","title":"Authorization Url","description":"Reddit OAuth approval URL."}},"type":"object","required":["authorization_url"],"title":"RedditOAuthStartResponse"},"RefreshAnalyticsJobResponse":{"properties":{"status":{"type":"string","const":"ok","title":"Status"},"workspaces":{"type":"integer","title":"Workspaces"},"refreshed":{"type":"integer","title":"Refreshed"},"failed_platforms":{"type":"integer","title":"Failed Platforms"},"workspaces_detail":{"items":{"$ref":"#/components/schemas/RefreshAnalyticsWorkspaceResult"},"type":"array","title":"Workspaces Detail","default":[]}},"type":"object","required":["status","workspaces","refreshed","failed_platforms"],"title":"RefreshAnalyticsJobResponse","example":{"failed_platforms":1,"refreshed":240,"status":"ok","workspaces":12,"workspaces_detail":[]}},"RefreshAnalyticsPlatformResult":{"properties":{"platform":{"type":"string","title":"Platform"},"status":{"type":"string","enum":["ok","partial","failed","skipped","unsupported"],"title":"Status"},"posts":{"type":"integer","title":"Posts"},"refreshed":{"type":"integer","title":"Refreshed"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["platform","status","posts","refreshed"],"title":"RefreshAnalyticsPlatformResult"},"RefreshAnalyticsWorkspaceResult":{"properties":{"workspace_id":{"type":"string","title":"Workspace Id"},"status":{"type":"string","enum":["ok","partial","failed","empty"],"title":"Status"},"refreshed":{"type":"integer","title":"Refreshed"},"platforms":{"items":{"$ref":"#/components/schemas/RefreshAnalyticsPlatformResult"},"type":"array","title":"Platforms","default":[]}},"type":"object","required":["workspace_id","status","refreshed"],"title":"RefreshAnalyticsWorkspaceResult"},"ScheduleVariantRequest":{"properties":{"scheduled_at":{"type":"string","format":"date-time","title":"Scheduled At","examples":["2026-07-08T10:30:00Z"]},"timezone":{"type":"string","minLength":1,"title":"Timezone","default":"UTC"}},"type":"object","required":["scheduled_at"],"title":"ScheduleVariantRequest","example":{"scheduled_at":"2026-07-08T10:30:00Z","timezone":"Asia/Calcutta"}},"SlackConnectRequest":{"properties":{"webhook_url":{"type":"string","minLength":1,"title":"Webhook Url","description":"Slack Incoming Webhook URL (https://hooks.slack.com/services/…).","examples":["https://hooks.slack.com/services/T000/B000/XXXX"]},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name","description":"Optional label for the channel.","examples":["#launches"]}},"type":"object","required":["webhook_url"],"title":"SlackConnectRequest"},"StatusResponse":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"StatusResponse","example":{"status":"ok"}},"StrategyRead":{"properties":{"workspace_id":{"type":"string","title":"Workspace Id"},"niche":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Niche"},"goals":{"items":{"type":"string"},"type":"array","title":"Goals"},"whats_new":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Whats New"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags"},"tone_profile":{"additionalProperties":true,"type":"object","title":"Tone Profile"},"voice_profile":{"$ref":"#/components/schemas/VoiceProfile"},"voice_samples":{"items":{"type":"string"},"type":"array","title":"Voice Samples"},"voice_sample_platforms":{"additionalProperties":{"type":"string"},"type":"object","title":"Voice Sample Platforms"},"voice_platforms_learned":{"items":{"type":"string"},"type":"array","title":"Voice Platforms Learned"},"cadence_per_week":{"type":"integer","title":"Cadence Per Week"},"platforms":{"items":{"type":"string"},"type":"array","title":"Platforms"},"automation":{"$ref":"#/components/schemas/AutomationSettings"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["workspace_id","niche","goals","tags","tone_profile","voice_profile","voice_samples","cadence_per_week","platforms","automation","updated_at"],"title":"StrategyRead","example":{"cadence_per_week":5,"goals":["grow","nurture"],"niche":"Indie SaaS / building in public","platforms":["x","linkedin"],"tone_profile":{"emoji":"sparse","tone_words":["wry","concise"]},"updated_at":"2026-07-14T10:00:00Z","workspace_id":"wks_123"}},"StrategyUpdate":{"properties":{"niche":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Niche"},"goals":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":12},{"type":"null"}],"title":"Goals"},"whats_new":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Whats New"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":40},{"type":"null"}],"title":"Tags"},"voice_profile":{"anyOf":[{"$ref":"#/components/schemas/VoiceProfile"},{"type":"null"}]},"voice_samples":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":50},{"type":"null"}],"title":"Voice Samples"},"voice_sample_platforms":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object","maxProperties":50},{"type":"null"}],"title":"Voice Sample Platforms"},"cadence_per_week":{"anyOf":[{"type":"integer","maximum":50.0,"minimum":1.0},{"type":"null"}],"title":"Cadence Per Week"},"platforms":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":20},{"type":"null"}],"title":"Platforms"},"automation":{"anyOf":[{"$ref":"#/components/schemas/AutomationSettings"},{"type":"null"}]}},"type":"object","title":"StrategyUpdate"},"SubscriptionRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"tier":{"type":"string","title":"Tier"},"plan_state":{"type":"string","title":"Plan State"},"plan_label":{"type":"string","title":"Plan Label"},"status":{"type":"string","title":"Status"},"renews_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Renews At"},"cancel_at_period_end":{"type":"boolean","title":"Cancel At Period End"},"billing_period":{"anyOf":[{"type":"string","enum":["monthly","yearly"]},{"type":"null"}],"title":"Billing Period"},"has_provider_subscription":{"type":"boolean","title":"Has Provider Subscription","default":false},"trial_eligible":{"type":"boolean","title":"Trial Eligible"},"included_credits":{"type":"integer","title":"Included Credits"},"channel_cap":{"type":"integer","title":"Channel Cap"}},"type":"object","required":["id","workspace_id","tier","plan_state","plan_label","status","renews_at","cancel_at_period_end","billing_period","trial_eligible","included_credits","channel_cap"],"title":"SubscriptionRead"},"TelegramConnectRequest":{"properties":{"bot_token":{"type":"string","minLength":1,"title":"Bot Token","description":"Bot token from @BotFather.","examples":["123456:ABC-DEF..."]},"chat_id":{"type":"string","minLength":1,"title":"Chat Id","description":"Target channel/group — @username or numeric chat id. The bot must be an admin.","examples":["@mychannel"]},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name","description":"Optional label.","examples":["Build Notes"]}},"type":"object","required":["bot_token","chat_id"],"title":"TelegramConnectRequest"},"TelegramLinkResponse":{"properties":{"bot_username":{"type":"string","title":"Bot Username"},"deep_link":{"type":"string","title":"Deep Link"},"token":{"type":"string","title":"Token"}},"type":"object","required":["bot_username","deep_link","token"],"title":"TelegramLinkResponse","description":"Deep link that adds the shared Cadencz bot to a channel."},"TextGenerationRequest":{"properties":{"input":{"type":"string","maxLength":8000,"minLength":1,"title":"Input","description":"Source material or instructions the model should turn into social copy.","examples":["We added Google sign-in and a safer backend auth flow for Cadencz."]},"platforms":{"items":{"type":"string"},"type":"array","maxItems":5,"minItems":1,"title":"Platforms","description":"One or more platform prompt templates to apply.","examples":[["twitter","linkedin"]]},"provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider","description":"Text model provider. Defaults to TEXT_MODEL_PROVIDER.","examples":["openai"]},"model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Model","description":"Provider model id. Defaults to OPENAI_MODEL for the OpenAI provider.","examples":["gpt-5.4-mini"]},"brain_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brain Id","description":"Optional Brain id/slug used to ground the generation in saved product knowledge.","examples":["brain_123"]},"conversation_id":{"anyOf":[{"type":"string","maxLength":36},{"type":"null"}],"title":"Conversation Id","description":"Optional durable Brain conversation to continue. Requires brain_id; when omitted, a new conversation is created for Brain-backed generation.","examples":["cnv_123"]},"conversation_message":{"anyOf":[{"type":"string","maxLength":8000,"minLength":1},{"type":"null"}],"title":"Conversation Message","description":"User-visible conversation turn to persist. Defaults to input when omitted, allowing clients to keep generation-only prompt instructions out of conversation history.","examples":["Turn our onboarding lesson into posts for this week."]},"brain_context":{"anyOf":[{"type":"string","maxLength":12000},{"type":"null"}],"title":"Brain Context","description":"Optional client-provided Brain context fallback when the Brain is not yet saved server-side."},"temperature":{"type":"number","maximum":2.0,"minimum":0.0,"title":"Temperature","default":0.7},"max_tokens":{"anyOf":[{"type":"integer","maximum":2000.0,"minimum":64.0},{"type":"null"}],"title":"Max Tokens"},"count":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Count","description":"How many distinct post concepts to create. When omitted, Compose infers an explicit count from requests such as 'write two posts'."},"content_guidance":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Content Guidance","description":"Selected content mode, kept separate from the user's requested subject."}},"type":"object","required":["input"],"title":"TextGenerationRequest","example":{"brain_id":"brain_123","conversation_id":"cnv_123","conversation_message":"Turn our onboarding lesson into posts for this week.","input":"We added Google sign-in and safer backend token validation.","max_tokens":500,"model":"gpt-5.4-mini","platforms":["twitter","linkedin"],"provider":"openai","temperature":0.7}},"TextGenerationResponse":{"properties":{"outputs":{"items":{"$ref":"#/components/schemas/GeneratedPlatformText"},"type":"array","title":"Outputs"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"}},"type":"object","required":["outputs"],"title":"TextGenerationResponse","example":{"conversation_id":"cnv_123","outputs":[{"agent_run_id":"run_123","model":"gpt-5.4-mini","platform":"twitter","provider":"openai","text":"Google sign-in is now live, with backend token checks doing the heavy lifting."},{"agent_run_id":"run_124","model":"gpt-5.4-mini","platform":"linkedin","provider":"openai","text":"We shipped Google sign-in with backend token validation. The important part is less visible: the frontend handles identity, while the API owns authorization and database writes."}]}},"ThreadsAccountInsightsResponse":{"properties":{"channel_id":{"type":"string","title":"Channel Id"},"handle":{"type":"string","title":"Handle"},"metrics":{"additionalProperties":{"type":"integer"},"type":"object","title":"Metrics","description":"Metric name to value. Absent metrics are omitted rather than zeroed.","examples":[{"followers_count":1420,"likes":96,"replies":12,"views":1820}]}},"type":"object","required":["channel_id","handle"],"title":"ThreadsAccountInsightsResponse","description":"Account-level Threads insights for one connected channel."},"ThreadsProfileLookupResponse":{"properties":{"username":{"type":"string","title":"Username"},"found":{"type":"boolean","title":"Found"},"profile":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Profile","examples":[{"follower_count":4000000,"is_verified":true,"name":"Mark Zuckerberg","username":"zuck","views_count":120000}]}},"type":"object","required":["username","found"],"title":"ThreadsProfileLookupResponse","description":"A public Threads profile, when Meta has one to give.\n\n`found` is false — not an error — for a handle that does not exist, is\nprivate, or sits under Meta's 100-follower disclosure floor."},"ToneAxis":{"properties":{"id":{"type":"string","maxLength":40,"title":"Id"},"low":{"type":"string","maxLength":40,"title":"Low"},"high":{"type":"string","maxLength":40,"title":"High"},"value":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Value","default":50}},"type":"object","required":["id","low","high"],"title":"ToneAxis","description":"One bipolar slider: `value` 0 sits at `low`, 100 at `high`."},"TopUpOption":{"properties":{"credits":{"type":"integer","title":"Credits"},"price_usd":{"type":"integer","title":"Price Usd"},"dodo_product_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dodo Product Id"}},"type":"object","required":["credits","price_usd","dodo_product_id"],"title":"TopUpOption","example":{"credits":500,"dodo_product_id":"prod_topup_500","price_usd":15}},"UpdateVariantRequest":{"properties":{"body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Body","examples":["Updated post copy for Bluesky."]},"media_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Media Ids"},"platform_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Target","examples":["r/test"]},"channel_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel Id","description":"Assign a channel to an unscheduled draft."}},"type":"object","title":"UpdateVariantRequest","example":{"body":"Updated post copy for Bluesky.","media_ids":[]}},"UserPreferences":{"properties":{"timezone":{"type":"string","title":"Timezone"},"weekStart":{"type":"string","title":"Weekstart","default":"monday"},"quietHours":{"type":"null","title":"Quiethours"}},"type":"object","required":["timezone"],"title":"UserPreferences","example":{"timezone":"Asia/Kolkata","weekStart":"monday"}},"UserPreferencesUpdate":{"properties":{"timezone":{"type":"string","maxLength":80,"minLength":1,"title":"Timezone"}},"type":"object","required":["timezone"],"title":"UserPreferencesUpdate"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VariantCreate":{"properties":{"channel_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel Id","examples":["chn_123"]},"platform":{"type":"string","title":"Platform","examples":["bluesky"]},"body":{"type":"string","minLength":1,"title":"Body","examples":["Shipping a compact update from Cadencz today."]},"media_ids":{"items":{"type":"string"},"type":"array","title":"Media Ids"},"platform_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Target","description":"Optional platform-specific destination, e.g. Reddit subreddit.","examples":["r/test"]},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled At","examples":["2026-07-08T10:30:00Z"]},"content_metadata":{"additionalProperties":true,"type":"object","title":"Content Metadata"},"thread_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thread Id"},"thread_position":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Thread Position"}},"type":"object","required":["platform","body"],"title":"VariantCreate"},"VariantRead":{"properties":{"id":{"type":"string","title":"Id"},"post_id":{"type":"string","title":"Post Id"},"channel_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Channel Id"},"platform":{"type":"string","title":"Platform"},"body":{"type":"string","title":"Body"},"media_ids":{"items":{"type":"string"},"type":"array","title":"Media Ids"},"media":{"items":{"$ref":"#/components/schemas/MediaRead"},"type":"array","title":"Media"},"platform_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Target"},"status":{"type":"string","title":"Status"},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled At"},"published_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Published At"},"provider_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Url"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"attempt_count":{"type":"integer","title":"Attempt Count"},"content_metadata":{"additionalProperties":true,"type":"object","title":"Content Metadata"},"thread_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thread Id"},"thread_position":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Thread Position"}},"type":"object","required":["id","post_id","channel_id","platform","body","media_ids","platform_target","status","scheduled_at","published_at","provider_url","error","attempt_count"],"title":"VariantRead","example":{"attempt_count":0,"body":"Cadencz now supports scheduled Bluesky posts.","channel_id":"chn_123","id":"var_123","media_ids":[],"platform":"bluesky","post_id":"pst_123","scheduled_at":"2026-07-08T10:30:00Z","status":"scheduled"}},"VoicePersona":{"properties":{"id":{"type":"string","maxLength":64,"title":"Id"},"name":{"type":"string","maxLength":80,"title":"Name","default":""},"audience":{"type":"string","maxLength":2000,"title":"Audience","default":""},"context":{"type":"string","maxLength":500,"title":"Context","default":""},"mission":{"type":"string","maxLength":2000,"title":"Mission","default":""},"traits":{"items":{"type":"string"},"type":"array","title":"Traits"},"goals":{"items":{"type":"string"},"type":"array","title":"Goals"},"tone":{"items":{"$ref":"#/components/schemas/ToneAxis"},"type":"array","maxItems":12,"title":"Tone"},"vocabulary":{"items":{"type":"string"},"type":"array","title":"Vocabulary"},"banned_words":{"items":{"type":"string"},"type":"array","title":"Banned Words"},"ctas":{"items":{"type":"string"},"type":"array","title":"Ctas"},"formatting":{"items":{"type":"string"},"type":"array","title":"Formatting"},"active":{"type":"boolean","title":"Active","default":false},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id"],"title":"VoicePersona","description":"A named way of speaking. Exactly one persona is active at a time."},"VoiceProfile":{"properties":{"personas":{"items":{"$ref":"#/components/schemas/VoicePersona"},"type":"array","maxItems":10,"title":"Personas"},"versions":{"items":{"$ref":"#/components/schemas/VoiceVersion"},"type":"array","maxItems":20,"title":"Versions"}},"type":"object","title":"VoiceProfile","description":"The whole authored document. Empty is valid — it just means untouched."},"VoiceVersion":{"properties":{"id":{"type":"string","maxLength":64,"title":"Id"},"persona_id":{"type":"string","maxLength":64,"title":"Persona Id"},"label":{"type":"string","maxLength":160,"title":"Label","default":""},"saved_at":{"type":"string","format":"date-time","title":"Saved At"},"snapshot":{"$ref":"#/components/schemas/VoicePersona"}},"type":"object","required":["id","persona_id","saved_at","snapshot"],"title":"VoiceVersion","description":"A snapshot taken on save, so a regretted edit is one click from undone."},"WaitlistAccessResponse":{"properties":{"early_access_granted":{"type":"boolean","title":"Early Access Granted"}},"type":"object","required":["early_access_granted"],"title":"WaitlistAccessResponse","example":{"early_access_granted":true}},"WaitlistJoinRequest":{"properties":{"email":{"type":"string","maxLength":320,"minLength":5,"title":"Email"},"source":{"type":"string","maxLength":80,"minLength":1,"title":"Source","default":"landing_page"},"website":{"type":"string","maxLength":200,"title":"Website","description":"Spam trap. Leave empty.","default":""}},"type":"object","required":["email"],"title":"WaitlistJoinRequest"},"WaitlistJoinResponse":{"properties":{"status":{"type":"string","title":"Status"},"joined":{"type":"boolean","title":"Joined"},"early_access_granted":{"type":"boolean","title":"Early Access Granted"}},"type":"object","required":["status","joined","early_access_granted"],"title":"WaitlistJoinResponse","example":{"early_access_granted":false,"joined":true,"status":"waiting"}},"WordPressConnectRequest":{"properties":{"site_url":{"type":"string","title":"Site Url","description":"Your site address.","examples":["example.com"]},"username":{"type":"string","title":"Username","description":"Your WordPress username.","examples":["akshay"]},"app_password":{"type":"string","title":"App Password","description":"Application password from Users -> Profile."},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name","description":"Optional label for the channel."}},"type":"object","required":["site_url","username","app_password"],"title":"WordPressConnectRequest","description":"Connect a self-hosted or WordPress.com site with an application password."},"WorkspaceCreateRequest":{"properties":{"name":{"type":"string","maxLength":200,"title":"Name"}},"type":"object","required":["name"],"title":"WorkspaceCreateRequest"},"WorkspaceDetail":{"properties":{"id":{"type":"string","title":"Id"},"ownerId":{"type":"string","title":"Ownerid"},"name":{"type":"string","title":"Name"},"handle":{"type":"string","title":"Handle"},"avatarUrl":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatarurl"},"createdAt":{"type":"string","title":"Createdat"},"isCurrent":{"type":"boolean","title":"Iscurrent"},"paused":{"type":"boolean","title":"Paused","default":false},"channels":{"type":"integer","title":"Channels"},"brains":{"type":"integer","title":"Brains"},"posts":{"type":"integer","title":"Posts"},"scheduled":{"type":"integer","title":"Scheduled"}},"type":"object","required":["id","ownerId","name","handle","avatarUrl","createdAt","isCurrent","channels","brains","posts","scheduled"],"title":"WorkspaceDetail","description":"A workspace as the management screen needs it: identity, plus enough of\nwhat is inside to make deleting it a decision rather than a guess."},"WorkspaceListResponse":{"properties":{"workspaces":{"items":{"$ref":"#/components/schemas/WorkspaceDetail"},"type":"array","title":"Workspaces"},"cap":{"type":"integer","title":"Cap"},"used":{"type":"integer","title":"Used"},"canCreate":{"type":"boolean","title":"Cancreate"},"role":{"type":"string","title":"Role","default":"owner"}},"type":"object","required":["workspaces","cap","used","canCreate"],"title":"WorkspaceListResponse"},"WorkspaceSwitchRequest":{"properties":{"workspaceId":{"type":"string","title":"Workspaceid"}},"type":"object","required":["workspaceId"],"title":"WorkspaceSwitchRequest"},"WorkspaceUpdateRequest":{"properties":{"name":{"type":"string","maxLength":200,"title":"Name"}},"type":"object","required":["name"],"title":"WorkspaceUpdateRequest"}},"securitySchemes":{"SupabaseBearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Supabase access token","description":"Send the Supabase access token as `Authorization: Bearer <token>`."},"DodoWebhookSignature":{"type":"apiKey","in":"header","name":"webhook-signature","description":"Dodo Payments webhook signature header."}}},"tags":[{"name":"health","description":"Service liveness checks."},{"name":"config","description":"Public application configuration."},{"name":"admin","description":"Admin-only configuration and operations."},{"name":"waitlist","description":"Public launch waitlist signup."},{"name":"me","description":"Current authenticated user and workspace."},{"name":"bootstrap","description":"One-request app-shell boot payload."},{"name":"channels","description":"Connected publishing accounts."},{"name":"generation","description":"AI-assisted social copy generation."},{"name":"agents","description":"Multi-agent graph runs and their per-agent trace."},{"name":"strategy","description":"Workspace agent strategy and voice learning."},{"name":"plans","description":"Weekly content planning and approvals."},{"name":"posts","description":"Posts, variants, scheduling, and publishing actions."},{"name":"billing","description":"Dodo Payments checkout and customer portal APIs."},{"name":"webhooks","description":"Provider webhook receivers."},{"name":"jobs","description":"Worker callbacks for scheduled publishing."}]}