{"openapi":"3.1.0","info":{"title":"TwinWrite Agent API","version":"1.0.0","description":"V1 surface for AI agents and power users. All endpoints are POST + JSON. Authentication: Bearer sk_live_… API keys.","contact":{"name":"TwinWrite","url":"https://twinwrite.com","email":"hello@twinwrite.com"}},"servers":[{"url":"https://twinwrite.com"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"sk_live_*"}},"schemas":{"ApiDraft":{"type":"object","required":["id","status","platform","locale","body","thread_items","image_url","feed_item_id","campaign_id","scheduled_for","created_at","updated_at"],"properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","approved","rejected","scheduled","posted","skipped"]},"platform":{"type":"string","enum":["linkedin","x"]},"locale":{"type":"string","description":"2-letter ISO 639-1 code"},"body":{"type":"string"},"thread_items":{"type":["array","null"],"items":{"type":"object","required":["content"],"properties":{"content":{"type":"string"}}}},"image_url":{"type":["string","null"]},"feed_item_id":{"type":["string","null"],"format":"uuid"},"campaign_id":{"type":["string","null"],"format":"uuid"},"scheduled_for":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"ApiFeed":{"type":"object","required":["id","url","kind","priority","active","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"title":{"type":["string","null"]},"kind":{"type":"string"},"priority":{"type":"integer"},"active":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}}},"ApiCampaign":{"type":"object","required":["id","title","post_count","mix_mode","status","context_urls","created_at"],"properties":{"id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":["string","null"]},"context_text":{"type":["string","null"]},"context_urls":{"type":"array","items":{"type":"string"}},"post_count":{"type":"integer","minimum":1,"maximum":50},"start_date":{"type":["string","null"],"format":"date-time"},"end_date":{"type":["string","null"],"format":"date-time"},"mix_mode":{"type":"string","enum":["rss_reframed","pure","mixed"]},"status":{"type":"string","enum":["active","paused","completed"]},"created_at":{"type":"string","format":"date-time"}}},"ApiBrandVoice":{"type":"object","required":["voice_profile","brand_questions"],"properties":{"voice_profile":{"type":["object","null"]},"brand_questions":{"type":["object","null"]},"linkedin_url":{"type":["string","null"]},"primary_language":{"type":["string","null"]},"secondary_language":{"type":["string","null"]},"x_language":{"type":["string","null"]}}},"AgentApiError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["missing_authorization","invalid_api_key","key_revoked","invalid_request","missing_field","invalid_field","unsupported_source","method_not_allowed","draft_not_found","draft_not_editable","draft_already_scheduled","feed_not_found","campaign_not_found","voice_not_found","late_not_connected","tenant_token_quota_exceeded","rate_limit_exceeded","concurrent_generation_cap","upstream_error","internal_error"]},"message":{"type":"string"},"retry_at":{"type":"string","format":"date-time"},"retry_after_seconds":{"type":"integer","minimum":1}}}}}}},"security":[{"bearerAuth":[]}],"paths":{"/api/v1/agent/drafts.generate":{"post":{"summary":"Generate drafts from a URL, topic, or campaign.","description":"Synchronous (~10–30s). Returns LinkedIn + X drafts in `pending` status. Honours tenant voice profile and the explicit `language` (or, if omitted, the tenant's primary/secondary language plan). Subject to the per-tenant daily token cap.","operationId":"drafts_generate","security":[{"bearerAuth":[]}],"tags":["drafts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source"],"properties":{"source":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["topic"],"properties":{"topic":{"type":"string","maxLength":600}}},{"type":"object","required":["campaign_id"],"properties":{"campaign_id":{"type":"string","format":"uuid"}}}]},"platforms":{"type":"array","items":{"type":"string","enum":["linkedin","x"]}},"language":{"type":"string","minLength":2,"maxLength":2}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","drafts"],"properties":{"ok":{"const":true},"drafts":{"type":"array","items":{"$ref":"#/components/schemas/ApiDraft"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/drafts.list":{"post":{"summary":"List drafts (cursor-paginated).","description":"Filter by API status. Returns up to `limit` drafts (default 50, max 100) plus an opaque `next_cursor`; pass it back to fetch the next page.","operationId":"drafts_list","security":[{"bearerAuth":[]}],"tags":["drafts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["pending","approved","rejected","scheduled","posted","skipped"]},"cursor":{"type":"string"},"limit":{"type":"integer","minimum":1,"maximum":100}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","drafts","next_cursor"],"properties":{"ok":{"const":true},"drafts":{"type":"array","items":{"$ref":"#/components/schemas/ApiDraft"}},"next_cursor":{"type":["string","null"]}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/drafts.get":{"post":{"summary":"Fetch one draft by id.","description":"Returns 404 if the draft is unknown or owned by another tenant.","operationId":"drafts_get","security":[{"bearerAuth":[]}],"tags":["drafts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["draft_id"],"properties":{"draft_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","draft"],"properties":{"ok":{"const":true},"draft":{"$ref":"#/components/schemas/ApiDraft"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/drafts.approve":{"post":{"summary":"Approve a pending draft.","description":"Flips status to `approved`. Optional `reason` is recorded as part of the approval log (no-op for V1).","operationId":"drafts_approve","security":[{"bearerAuth":[]}],"tags":["drafts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["draft_id"],"properties":{"draft_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","draft"],"properties":{"ok":{"const":true},"draft":{"$ref":"#/components/schemas/ApiDraft"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/drafts.reject":{"post":{"summary":"Reject a pending draft.","description":"Flips status to `rejected`. Subsequent `drafts.schedule` is rejected.","operationId":"drafts_reject","security":[{"bearerAuth":[]}],"tags":["drafts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["draft_id"],"properties":{"draft_id":{"type":"string","format":"uuid"},"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","draft"],"properties":{"ok":{"const":true},"draft":{"$ref":"#/components/schemas/ApiDraft"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/drafts.update":{"post":{"summary":"Edit a draft body (LinkedIn) or thread items (X).","description":"Locked once the draft leaves `pending`. Provide `body` for LinkedIn drafts, `thread_items` for X drafts.","operationId":"drafts_update","security":[{"bearerAuth":[]}],"tags":["drafts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["draft_id"],"properties":{"draft_id":{"type":"string","format":"uuid"},"body":{"type":"string"},"thread_items":{"type":"array","items":{"type":"object","required":["content"],"properties":{"content":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","draft"],"properties":{"ok":{"const":true},"draft":{"$ref":"#/components/schemas/ApiDraft"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/drafts.schedule":{"post":{"summary":"Schedule a draft for publishing via Late.","description":"Auto-approves the draft if it is currently `pending`. Rejected/posted drafts are not eligible.","operationId":"drafts_schedule","security":[{"bearerAuth":[]}],"tags":["drafts"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["draft_id","scheduled_at"],"properties":{"draft_id":{"type":"string","format":"uuid"},"scheduled_at":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","draft","scheduled_at"],"properties":{"ok":{"const":true},"draft":{"$ref":"#/components/schemas/ApiDraft"},"scheduled_at":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/feeds.list":{"post":{"summary":"List the tenant's feed sources.","description":"Includes both active and inactive sources.","operationId":"feeds_list","security":[{"bearerAuth":[]}],"tags":["feeds"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","feeds"],"properties":{"ok":{"const":true},"feeds":{"type":"array","items":{"$ref":"#/components/schemas/ApiFeed"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/feeds.add":{"post":{"summary":"Add an RSS feed by URL or discover from a LinkedIn paste.","description":"Pass `{ url }` to add a single feed directly, or `{ linkedin_paste }` to receive AI-generated feed suggestions.","operationId":"feeds_add","security":[{"bearerAuth":[]}],"tags":["feeds"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}},{"type":"object","required":["linkedin_paste"],"properties":{"linkedin_paste":{"type":"string"}}}]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"oneOf":[{"type":"object","required":["ok","feed"],"properties":{"ok":{"const":true},"feed":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":["string","null"]},"item_count":{"type":"integer"}}}}},{"type":"object","required":["ok","suggestions"],"properties":{"ok":{"const":true},"suggestions":{"type":"array","items":{"type":"object","required":["url","title","rationale"],"properties":{"url":{"type":"string"},"title":{"type":"string"},"rationale":{"type":"string"}}}}}}]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/feeds.remove":{"post":{"summary":"Soft-delete a feed source (sets active=false).","description":"Historical feed_items are preserved so draft provenance survives.","operationId":"feeds_remove","security":[{"bearerAuth":[]}],"tags":["feeds"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["feed_id"],"properties":{"feed_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","feed_id"],"properties":{"ok":{"const":true},"feed_id":{"type":"string","format":"uuid"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/voice.read":{"post":{"summary":"Read the tenant's brand voice profile.","description":"Returns voice_profile + brand_questions verbatim plus the language settings used by the pipeline.","operationId":"voice_read","security":[{"bearerAuth":[]}],"tags":["voice"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","voice_profile","brand_questions"],"properties":{"ok":{"const":true},"voice_profile":{"type":["object","null"]},"brand_questions":{"type":["object","null"]},"linkedin_url":{"type":["string","null"]},"primary_language":{"type":["string","null"]},"secondary_language":{"type":["string","null"]},"x_language":{"type":["string","null"]}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/campaigns.list":{"post":{"summary":"List campaigns for the tenant.","description":"Newest first.","operationId":"campaigns_list","security":[{"bearerAuth":[]}],"tags":["campaigns"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","campaigns"],"properties":{"ok":{"const":true},"campaigns":{"type":"array","items":{"$ref":"#/components/schemas/ApiCampaign"}}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/campaigns.create":{"post":{"summary":"Create a campaign.","description":"A tenant may have at most one `active` campaign at a time. The created row defaults to `active`.","operationId":"campaigns_create","security":[{"bearerAuth":[]}],"tags":["campaigns"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","post_count"],"properties":{"title":{"type":"string","maxLength":200},"description":{"type":["string","null"]},"context_text":{"type":["string","null"]},"context_urls":{"type":"array","items":{"type":"string","format":"uri"}},"post_count":{"type":"integer","minimum":1,"maximum":50},"start_date":{"type":["string","null"],"format":"date-time"},"end_date":{"type":["string","null"],"format":"date-time"},"mix_mode":{"type":"string","enum":["rss_reframed","pure","mixed"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","campaign"],"properties":{"ok":{"const":true},"campaign":{"$ref":"#/components/schemas/ApiCampaign"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/campaigns.update":{"post":{"summary":"Partially update a campaign.","description":"Only fields you supply are PATCHed. Setting `status: \"active\"` enforces the one-active-at-a-time invariant.","operationId":"campaigns_update","security":[{"bearerAuth":[]}],"tags":["campaigns"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["campaign_id"],"properties":{"campaign_id":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":["string","null"]},"context_text":{"type":["string","null"]},"context_urls":{"type":"array","items":{"type":"string"}},"post_count":{"type":"integer","minimum":1,"maximum":50},"start_date":{"type":["string","null"],"format":"date-time"},"end_date":{"type":["string","null"],"format":"date-time"},"mix_mode":{"type":"string","enum":["rss_reframed","pure","mixed"]},"status":{"type":"string","enum":["active","paused","completed"]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","campaign"],"properties":{"ok":{"const":true},"campaign":{"$ref":"#/components/schemas/ApiCampaign"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}},"/api/v1/agent/campaigns.deactivate":{"post":{"summary":"Deactivate (pause) a campaign.","description":"Maps to internal status `paused`. Use `campaigns.update` with `status` to activate.","operationId":"campaigns_deactivate","security":[{"bearerAuth":[]}],"tags":["campaigns"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["campaign_id"],"properties":{"campaign_id":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","required":["ok","campaign"],"properties":{"ok":{"const":true},"campaign":{"$ref":"#/components/schemas/ApiCampaign"}}}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"401":{"description":"Authentication failed (missing/invalid/revoked API key)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"404":{"description":"Resource not found in this tenant","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"409":{"description":"State conflict (e.g. draft not editable)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"422":{"description":"Unsupported source variant or domain validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"429":{"description":"Throttled: per-key rate limit (`rate_limit_exceeded`), per-tenant concurrent-generation cap (`concurrent_generation_cap`), or daily token quota exhausted (`tenant_token_quota_exceeded`). Includes a `Retry-After` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"500":{"description":"Internal error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}},"502":{"description":"Upstream model / fetcher error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentApiError"}}}}}}}}}