{"openapi":"3.1.0","info":{"title":"The Agent C API","description":"AI COO platform — Jarvis Jr. manages your social media content.","version":"0.1.0"},"paths":{"/v1/health":{"get":{"tags":["health"],"summary":"Health Check","description":"Basic health check — confirms the API process is alive.","operationId":"health_check_v1_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/health/db":{"get":{"tags":["health"],"summary":"Db Health Check","description":"Database health check — confirms Postgres is reachable.\nRailway uses this to verify the full stack is operational.","operationId":"db_health_check_v1_health_db_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/auth/onboard":{"post":{"tags":["auth"],"summary":"Onboard User","description":"Called once after Firebase signup to create the user + workspace in Postgres.\nRequires a valid Firebase token in the Authorization header.","operationId":"onboard_user_v1_auth_onboard_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/me":{"get":{"tags":["auth"],"summary":"Get Me","description":"Returns the current user's profile + workspace details.\nThis is the first call the dashboard makes after login.\n\nFreemium invariant (2026-06-20): free is the DEFAULT state — there is no\nwalled state. Legacy pre-freemium workspaces can still carry\nstatus=\"pending_payment\" (created before the pivot, never paid) or\n\"churned\" (sub ended); both used to dead-end users on /choose-plan with\nno way into the free tier (the client guard bounced the \"keep using\nfree\" link straight back). Normalize them to free/active lazily here —\n/me is the dashboard's first call, so the account self-heals on login.\npast_due is left alone (Stripe is still retrying; the client guard keeps\nthe dashboard accessible for it).","operationId":"get_me_v1_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Me V1 Me Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/workspace":{"get":{"tags":["workspaces"],"summary":"Get Workspace","description":"Get current workspace details including credit balance and plan.","operationId":"get_workspace_v1_workspace_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceRead"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["workspaces"],"summary":"Update Workspace","description":"Update workspace settings (name, autonomy, owner display name, onboarding).","operationId":"update_workspace_v1_workspace_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceUpdate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkspaceRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/brands":{"get":{"tags":["brands"],"summary":"List Brands","description":"List all brands in the current workspace.","operationId":"list_brands_v1_brands_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BrandRead"},"type":"array","title":"Response List Brands V1 Brands Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["brands"],"summary":"Create Brand","description":"Create a new brand in the current workspace.","operationId":"create_brand_v1_brands_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/brands/{brand_id}":{"get":{"tags":["brands"],"summary":"Get Brand","description":"Get a specific brand by ID (must belong to current workspace).","operationId":"get_brand_v1_brands__brand_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Brand Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["brands"],"summary":"Update Brand","description":"Update a brand's config, SOUL, or brand kit.","operationId":"update_brand_v1_brands__brand_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Brand Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__schemas__brand__BrandUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/campaigns":{"get":{"tags":["campaigns"],"summary":"List Campaigns","description":"List all campaigns in the current workspace with optional filtering.\n\nQuery parameters:\n- status: Filter by campaign status (draft, active, paused, completed)\n- brand_id: Filter campaigns for a specific brand\n- limit: Number of results (max 100)\n- offset: Pagination offset","operationId":"list_campaigns_v1_campaigns_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"brand_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Brand Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["campaigns"],"summary":"Create Campaign","description":"Create a new campaign for a brand in the current workspace.\nThe brand must exist in the current workspace.","operationId":"create_campaign_v1_campaigns_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/campaigns/{campaign_id}":{"get":{"tags":["campaigns"],"summary":"Get Campaign","description":"Get a specific campaign by ID with all details.\nCampaign must belong to a brand in the current workspace.","operationId":"get_campaign_v1_campaigns__campaign_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["campaigns"],"summary":"Update Campaign","description":"Update an existing campaign.\nCannot directly change status to 'active' — use /pause or /resume endpoints instead.","operationId":"update_campaign_v1_campaigns__campaign_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["campaigns"],"summary":"Delete Campaign","description":"Soft delete a campaign by setting its status to 'archived'.\nThe campaign record remains in the database for historical reference.","operationId":"delete_campaign_v1_campaigns__campaign_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/campaigns/{campaign_id}/activate":{"post":{"tags":["campaigns"],"summary":"Activate Campaign","description":"Activate a draft (or completed) campaign so the scheduler starts dispatching\nruns according to its cadence.\n\nComputes `next_run_at` from the campaign's cadence. If the campaign has no\ncadence, activation is still allowed but the scheduler will treat it as a\none-shot (next dispatch will mark it completed).","operationId":"activate_campaign_v1_campaigns__campaign_id__activate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignStatusChange"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/campaigns/{campaign_id}/pause":{"post":{"tags":["campaigns"],"summary":"Pause Campaign","description":"Pause an active campaign. Scheduled runs will not be triggered.\nOnly active campaigns can be paused.","operationId":"pause_campaign_v1_campaigns__campaign_id__pause_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignStatusChange"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/campaigns/{campaign_id}/resume":{"post":{"tags":["campaigns"],"summary":"Resume Campaign","description":"Resume a paused campaign. Scheduled runs will resume according to cadence.\nOnly paused campaigns can be resumed.","operationId":"resume_campaign_v1_campaigns__campaign_id__resume_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignStatusChange"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/content":{"get":{"tags":["content"],"summary":"List Content","description":"List content items for the current workspace.\n\nSupports filtering by status, brand, and platform.\nResults are paginated and ordered by creation date (newest first).","operationId":"list_content_v1_content_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status Filter"},"description":"Filter by status"},{"name":"brand_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter by brand","title":"Brand Id"},"description":"Filter by brand"},{"name":"platform","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by platform","title":"Platform"},"description":"Filter by platform"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":250,"minimum":1,"description":"Items per page","default":50,"title":"Limit"},"description":"Items per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ContentRead"},"title":"Response List Content V1 Content Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["content"],"summary":"Create Content","description":"Create a new content item in draft status.\n\nThe brand_id must belong to the current workspace.\nContent is initially created as a draft and can be published later.","operationId":"create_content_v1_content_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/content/{content_id}":{"get":{"tags":["content"],"summary":"Get Content","description":"Get a specific content item by ID (must belong to workspace).","operationId":"get_content_v1_content__content_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"content_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Content Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["content"],"summary":"Update Content","description":"Update a content item.\n\nCan only update content in draft or pending_approval status.\nPublished content cannot be modified.","operationId":"update_content_v1_content__content_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"content_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Content Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["content"],"summary":"Delete Content","description":"Soft delete a content item (set status to 'archived').\n\nThe item remains in the database for audit purposes but is\nhidden from normal list queries. This is reversible.","operationId":"delete_content_v1_content__content_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"content_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Content Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/content/{content_id}/publish":{"post":{"tags":["content"],"summary":"Publish Content","description":"Publish a content item.\n\nThis endpoint:\n1. Verifies the content belongs to the workspace\n2. Calculates credit cost based on mode + content type\n3. Checks if workspace has sufficient credits\n4. Deducts credits and updates content status\n5. Returns the updated content item\n\nIf credit deduction fails, the content status remains unchanged.","operationId":"publish_content_v1_content__content_id__publish_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"content_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Content Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentPublishRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/content/stats":{"get":{"tags":["content"],"summary":"Get Content Stats","description":"Get aggregate content statistics for the workspace.\n\nReturns:\n- Total count of content items\n- Breakdown by status (draft, pending_approval, posted, etc.)\n- Breakdown by platform (x, youtube, instagram, etc.)\n- Total posted items\n- Items posted today","operationId":"get_content_stats_v1_content_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContentStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/credits":{"get":{"tags":["credits"],"summary":"Get Credit Balance","description":"Get current credit balance and usage information.\n\nReturns the user's credit balance, plan tier, video cap progress,\nand strategy session allocation for their workspace.","operationId":"get_credit_balance_v1_credits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditBalance"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/credits/history":{"get":{"tags":["credits"],"summary":"Get Credit History","description":"Get paginated credit ledger history.\n\nReturns past credit transactions with newest first.\nUseful for auditing and understanding usage patterns.","operationId":"get_credit_history_v1_credits_history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Items per page","default":50,"title":"Limit"},"description":"Items per page"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Pagination offset","default":0,"title":"Offset"},"description":"Pagination offset"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditHistory"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/credits/usage":{"get":{"tags":["credits"],"summary":"Get Usage Summary","description":"Get aggregate credit usage for the current billing period.\n\nShows total spent, earned, and breakdown by reason.\nUseful for understanding where credits are being consumed.","operationId":"get_usage_summary_v1_credits_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageSummary"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/credits/check":{"post":{"tags":["credits"],"summary":"Check Credits","description":"Pre-flight check: do we have enough credits for an operation?\n\nUse this before executing expensive operations to give users\nclear feedback about whether they can proceed.\n\nThe 'action' parameter should be one of:\n- mode_1_text (1 credit)\n- mode_1_video (6 credits)\n- mode_2_campaign_text (2 credits)\n- mode_2_campaign_video (8 credits)\n- mode_3_text (4 credits)\n- mode_3_video (15 credits)\n- extra_strategy_session (50 credits)","operationId":"check_credits_v1_credits_check_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditCheckRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditCheckResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/credits/purchase":{"post":{"tags":["credits"],"summary":"Purchase Overage Pack","description":"DISABLED. This used to grant credits directly with no payment — a faucet\nthat, with free accounts now active, would let anyone self-grant unlimited\ncredits. Credit packs are now retired entirely (POST /v1/billing/credit-pack\n410s too). Kept as a 410 so any stale client gets a clear message.","operationId":"purchase_overage_pack_v1_credits_purchase_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OveragePackPurchaseRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OveragePackPurchaseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/jr/chat":{"post":{"tags":["Jr. (COO Engine)"],"summary":"Chat with Jr.","description":"Send a message to Jr., the creative director. Single JSON response. Token-metered: 1 credit per 10k tokens accrued across messages.","operationId":"jr_chat_v1_jr_chat_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Jr Chat V1 Jr Chat Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/jr/strategy":{"post":{"tags":["Jr. (COO Engine)"],"summary":"Start strategy session","description":"Request an Opus-powered deep strategy session. Costs 50 credits.","operationId":"jr_strategy_v1_jr_strategy_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StrategyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/jr/dispatch":{"post":{"tags":["Jr. (COO Engine)"],"summary":"Dispatch content pipeline run","description":"Enqueue a content pipeline run. Credits are deducted when the run executes.","operationId":"jr_dispatch_v1_jr_dispatch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DispatchRunRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DispatchRunResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/jr/sessions":{"get":{"tags":["Jr. (COO Engine)"],"summary":"List chat sessions","description":"List recent chat sessions for the current user.","operationId":"list_chat_sessions_v1_jr_sessions_get","security":[{"HTTPBearer":[]}],"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/ChatSessionRead"},"title":"Response List Chat Sessions V1 Jr Sessions Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/jr/sessions/{session_id}":{"get":{"tags":["Jr. (COO Engine)"],"summary":"Get chat session detail","description":"Get a chat session with full message history.","operationId":"get_chat_session_v1_jr_sessions__session_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatSessionDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/runs":{"get":{"tags":["runs"],"summary":"List Runs","description":"List pipeline runs for the current workspace.","operationId":"list_runs_v1_runs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["runs"],"summary":"Create Run","description":"Create a new one-off pipeline run.\n\nThis is what the `/content/new` dashboard form calls. It validates the\nrequest, verifies the brand belongs to the caller's workspace, pre-checks\ncredits and the monthly video cap, creates a Run row, and enqueues a\nJob for the worker to pick up.\n\nWe do NOT deduct credits here — the worker does that when the run\nactually executes. This prevents charging for queued-but-never-run\njobs (e.g., the worker dies before dequeue) and matches the pattern\nused by `coo_engine.dispatch_run`. The pre-check below is just a\nfast-fail so the UI can tell the customer \"you don't have enough\ncredits\" before filling out a form.\n\nReturns the persisted Run so the dashboard can redirect to\n`/content/runs/{id}` and start polling progress immediately.","operationId":"create_run_v1_runs_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunCreateInput"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunListItem"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/runs/{run_id}":{"get":{"tags":["runs"],"summary":"Get Run","description":"Get detailed run info including checkpoint progress.","operationId":"get_run_v1_runs__run_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunDetail"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/runs/{run_id}/progress":{"get":{"tags":["runs"],"summary":"Get Run Progress","description":"Get live step-by-step progress for dashboard display.","operationId":"get_run_progress_v1_runs__run_id__progress_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProgressResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/runs/{run_id}/retry":{"post":{"tags":["runs"],"summary":"Retry Run","description":"Retry a failed run from its last checkpoint.\nOnly failed runs can be retried. Completed steps are skipped.","operationId":"retry_run_v1_runs__run_id__retry_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"run_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Run Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/system/breakers":{"get":{"tags":["runs"],"summary":"Get Circuit Breakers","description":"Get circuit breaker status for all external services.\nUseful for admin dashboard and debugging.","operationId":"get_circuit_breakers_v1_system_breakers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BreakerStatus"},"type":"array","title":"Response Get Circuit Breakers V1 System Breakers Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/analytics/overview":{"get":{"tags":["analytics"],"summary":"Get Analytics Overview","description":"Get top-line analytics overview for the workspace.\n\nReturns:\n- total_content: Total content pieces created\n- content_by_type: Breakdown by content type (text, image, video, thread, carousel, pin)\n- content_by_platform: Breakdown by platform (x, youtube, pinterest, instagram)\n- content_status_breakdown: Breakdown by status (draft, pending_approval, approved, posted, failed)\n- total_runs: Total pipeline runs executed\n- successful_runs: Runs with status=completed\n- failed_runs: Runs with status=failed\n- total_credits_used: Total credits consumed this period\n- average_credits_per_run: Average credits used per run\n- content_posted_this_month: Count of posted content","operationId":"get_analytics_overview_v1_analytics_overview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Analytics Overview V1 Analytics Overview Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/analytics/content-performance":{"get":{"tags":["analytics"],"summary":"Get Content Performance","description":"Get content performance metrics.\n\nReturns:\n- by_content_type: Performance metrics grouped by content type\n- by_platform: Performance metrics grouped by platform\n- time_series: Daily breakdown of content creation and posting over the period\n- total_created: Total content created in period\n- total_posted: Total content posted in period\n- total_failed: Total content that failed","operationId":"get_content_performance_v1_analytics_content_performance_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to analyze","default":30,"title":"Days"},"description":"Number of days to analyze"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Content Performance V1 Analytics Content Performance Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/analytics/credit-usage":{"get":{"tags":["analytics"],"summary":"Get Credit Usage","description":"Get credit usage breakdown over time.\n\nReturns:\n- total_spent: Total credits spent in period\n- total_added: Total credits added in period (resets, purchases)\n- by_reason: Breakdown by transaction reason\n- time_series: Daily credit usage over the period\n- average_daily_spend: Average credits consumed per day","operationId":"get_credit_usage_v1_analytics_credit_usage_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to analyze","default":30,"title":"Days"},"description":"Number of days to analyze"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Credit Usage V1 Analytics Credit Usage Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/platforms/connect":{"post":{"tags":["platforms"],"summary":"Connect Platform","description":"Initiate OAuth flow for connecting a social platform.\n\nReturns an authorization_url that the frontend should redirect\nthe user to. After the user authorizes, the platform redirects\nback to the specified redirect_uri with a code and state.","operationId":"connect_platform_v1_platforms_connect_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/platforms/callback":{"post":{"tags":["platforms"],"summary":"Handle Oauth Callback","description":"Handle the OAuth callback from the platform.\n\nExchanges the authorization code for access + refresh tokens,\nfetches the user's profile, and saves credentials to the brand.","operationId":"handle_oauth_callback_v1_platforms_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallbackResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/platforms/status":{"get":{"tags":["platforms"],"summary":"Get Platform Status","description":"Get connection status of all platforms for a brand.\n\nReturns which platforms are connected, the account username,\nand whether a posting adapter is available.","operationId":"get_platform_status_v1_platforms_status_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"brand_id","in":"query","required":true,"schema":{"type":"string","format":"uuid","description":"Brand to check","title":"Brand Id"},"description":"Brand to check"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlatformStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/platforms/{brand_id}/{platform}":{"delete":{"tags":["platforms"],"summary":"Disconnect Platform","description":"Disconnect a platform from a brand.\n\nRemoves the stored OAuth credentials. The user will need to\nre-authenticate to post to this platform again.","operationId":"disconnect_platform_v1_platforms__brand_id___platform__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Brand Id"}},{"name":"platform","in":"path","required":true,"schema":{"type":"string","title":"Platform"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/platforms/publish/{content_id}":{"post":{"tags":["platforms"],"summary":"Publish To Platform","description":"Publish a content item to its target platform.\n\nThis endpoint:\n1. Loads the content and its platform credentials\n2. Auto-refreshes expired tokens\n3. Posts via the platform adapter (X, YouTube, etc.)\n4. Updates the content record with the result\n\nThe content must be in a publishable state (draft, approved,\nor pending_approval). Credits should already be deducted via\nthe /content/{id}/publish endpoint before calling this.","operationId":"publish_to_platform_v1_platforms_publish__content_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"content_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Content Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublishResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/platforms/boards/{brand_id}":{"get":{"tags":["platforms"],"summary":"List Pinterest Boards","description":"List Pinterest boards for a connected brand.\n\nUsed by the dashboard to let customers choose which board\nto pin content to. Only available when Pinterest is connected.","operationId":"list_pinterest_boards_v1_platforms_boards__brand_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"brand_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Brand Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/plans":{"get":{"tags":["billing"],"summary":"List Plans","description":"Public endpoint — returns available plans for the choose-plan page.\nNo auth required so the paywall page can render plans.","operationId":"list_plans_v1_billing_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Plans V1 Billing Plans Get"}}}}}}},"/v1/billing/checkout":{"post":{"tags":["billing"],"summary":"Create Checkout Session","description":"Create a Stripe Checkout session for plan subscription.\n\nArgs:\n    plan: One of \"builder\", \"studio\", \"builder_founder\", \"studio_founder\",\n        \"builder_annual\", \"studio_annual\"\n\nReturns:\n    - session_id: Stripe session ID for checkout\n    - url: URL to redirect user to for checkout\n    - plan: Plan tier selected\n    - price_cents: Price in cents","operationId":"create_checkout_session_v1_billing_checkout_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"plan","in":"query","required":true,"schema":{"type":"string","title":"Plan"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Checkout Session V1 Billing Checkout Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/billing/portal":{"post":{"tags":["billing"],"summary":"Create Portal Session","description":"Create a Stripe Customer Portal session for plan management.\n\nUsers can view/modify their subscription, update payment method, view invoices, etc.\n\nReturns:\n    - url: URL to redirect user to the Customer Portal","operationId":"create_portal_session_v1_billing_portal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Create Portal Session V1 Billing Portal Post"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/billing/webhook":{"post":{"tags":["billing"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.\n\nIMPORTANT: This endpoint does NOT require authentication.\nInstead, we verify the webhook signature using Stripe's signing secret.\n\nHandles events:\n- checkout.session.completed: User completed checkout, activate subscription\n- customer.subscription.updated: Subscription details changed\n- customer.subscription.deleted: Subscription cancelled\n- invoice.paid: Invoice payment succeeded","operationId":"stripe_webhook_v1_billing_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Stripe Webhook V1 Billing Webhook Post"}}}}}}},"/v1/billing/subscription":{"get":{"tags":["billing"],"summary":"Get Subscription","description":"Get current subscription details for the workspace.\n\nReturns:\n- plan: Current plan tier\n- status: Subscription status (active, past_due, cancelled, etc.)\n- stripe_customer_id: Stripe customer ID\n- stripe_subscription_id: Stripe subscription ID\n- credits_total: Total credits allocated to this plan\n- credits_remaining: Credits remaining\n- video_cap: Video limit per month\n- video_used: Videos used this month\n- strategy_sessions: Strategy sessions included\n- renewal_date: Next renewal date (if active)","operationId":"get_subscription_v1_billing_subscription_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Get Subscription V1 Billing Subscription Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/billing/invoices":{"get":{"tags":["billing"],"summary":"List Invoices","description":"Real Stripe invoice history for the workspace's customer.","operationId":"list_invoices_v1_billing_invoices_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Invoices V1 Billing Invoices Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/billing/credit-pack":{"post":{"tags":["billing"],"summary":"Purchase Credit Pack","description":"RETIRED — always 410. Credit packs are no longer sold (pay-per-set $9.99\nunlocks + the Studio subscription replaced them). Existing pack payments are\nstill honoured by the webhook (handle_credit_pack_completed); credit columns\nand ledger data are untouched.","operationId":"purchase_credit_pack_v1_billing_credit_pack_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"pack","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pack"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Purchase Credit Pack V1 Billing Credit Pack Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps":{"get":{"tags":["creative-apps"],"summary":"List Apps","description":"List the workspace's app listings, newest first, with concept counts.","operationId":"list_apps_v1_apps_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/AppListingRead"},"type":"array","title":"Response List Apps V1 Apps Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["creative-apps"],"summary":"Create App","description":"Add an app. Live apps (app_store_url) ingest store metadata/reviews;\nunreleased apps create a ready draft you upload screenshots to and run the\nASC/creative pipeline against — no store lookup.","operationId":"create_app_v1_apps_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/apps/{listing_id}/go-live":{"post":{"tags":["creative-apps"],"summary":"Go Live","description":"Promote a draft (unreleased) app to LIVE by linking its App Store URL.\nResolves the Apple id, then runs the same ingest as a live app — keeping the\nscreenshots/brand you already uploaded to the draft (ingest merges, not wipes).","operationId":"go_live_v1_apps__listing_id__go_live_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoLiveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}":{"get":{"tags":["creative-apps"],"summary":"Get App","description":"Get a listing incl. brand_tokens and a review-corpus summary.","operationId":"get_app_v1_apps__listing_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppListingRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["creative-apps"],"summary":"Delete App","description":"Delete a listing and everything under it. Children are removed explicitly\nin dependency order (assets → batches → concepts → listing) with core DELETEs\nrather than relying on ORM/DB cascade — a listing with generated creatives\notherwise fails to delete (the relationships have no delete cascade, and the\nDB's FK constraints may predate the models' ondelete). Lets users clean up\nduplicates / wrong apps.","operationId":"delete_app_v1_apps__listing_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/screenshots":{"post":{"tags":["creative-apps"],"summary":"Upload Screenshots","description":"Upload RAW app screen captures. These become the real UI composited\ninto generated App Store screenshot designs (so output is submittable,\nnot AI-invented UI). Stored on listing.metadata_['uploaded_screenshots'].","operationId":"upload_screenshots_v1_apps__listing_id__screenshots_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_screenshots_v1_apps__listing_id__screenshots_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppListingRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["creative-apps"],"summary":"Clear Screenshots","description":"Remove all uploaded raw screenshots for a listing.","operationId":"clear_screenshots_v1_apps__listing_id__screenshots_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppListingRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/brand/refresh":{"post":{"tags":["creative-apps"],"summary":"Refresh Brand","description":"Re-extract brand tokens from the app's icon + screenshots with the\ncurrent algorithm. Fixes listings whose colors were extracted by an\nearlier, muddier version (no full re-ingest).","operationId":"refresh_brand_v1_apps__listing_id__brand_refresh_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppListingRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/brand":{"patch":{"tags":["creative-apps"],"summary":"Update Brand","description":"Edit brand tokens by hand (the editable brand kit). Any field set here\nis pinned (_locked) so a later brand refresh won't overwrite it.","operationId":"update_brand_v1_apps__listing_id__brand_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__schemas__creative__BrandUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppListingRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/concepts/generate":{"post":{"tags":["creative-apps"],"summary":"Generate Concepts","description":"Enqueue a concept-mining job for a ready listing.","operationId":"generate_concepts_v1_apps__listing_id__concepts_generate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConceptGenerateRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConceptGenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/concepts":{"get":{"tags":["creative-apps"],"summary":"List Concepts","description":"List concepts for a listing (newest first).","operationId":"list_concepts_v1_apps__listing_id__concepts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ConceptRead"},"title":"Response List Concepts V1 Apps  Listing Id  Concepts Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/assets":{"get":{"tags":["creative-apps"],"summary":"List App Assets","description":"This app's finished creatives (newest first) with freshly-signed URLs —\nthe per-app gallery. Only ``ready`` assets; pending/failed are hidden.\nImage assets still missing a thumbnail get one generated in the background\n(bounded per request) so the next load serves the small webp.","operationId":"list_app_assets_v1_apps__listing_id__assets_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":60,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GalleryAssetRead"},"title":"Response List App Assets V1 Apps  Listing Id  Assets Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/concepts/{concept_id}":{"patch":{"tags":["creative-apps"],"summary":"Update Concept","description":"Approve/edit a concept (must belong to the caller's workspace).","operationId":"update_concept_v1_concepts__concept_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"concept_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Concept Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConceptUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConceptRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/asc-themes":{"post":{"tags":["creative-apps"],"summary":"Suggest Asc Themes","description":"Propose distinct, on-theme background atmospheres for this app's ASC set.\nThe user picks one (or sends a `hint` to steer); the chosen theme.prompt is\npassed to POST /cpp-sets and injected into the panorama background.","operationId":"suggest_asc_themes_v1_apps__listing_id__asc_themes_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AscThemesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AscThemesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/cpp-sets":{"post":{"tags":["creative-apps"],"summary":"Create Cpp Set","description":"Create a CPP screenshot-set batch: screenshot_frame renders per\n(concept x up to 4 source screenshots) + promo text per concept.\nCredit-gated at CREATIVE_CREDIT_COSTS['cpp_set'] per concept.","operationId":"create_cpp_set_v1_apps__listing_id__cpp_sets_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CppSetCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/cpp-sets/preview":{"post":{"tags":["creative-apps"],"summary":"Preview Cpp Set","description":"Free, fast, live preview of the CPP screenshot-set builder: renders the\nREAL pipeline at 25% scale (or `scale` if given) so the builder UI can\nshow a live view as the user tweaks layout/headlines/theme.\n\nTwo response shapes, selected by `body.slide`:\n  - `slide` omitted/null: the full-strip render — one composited strip of\n    all 6 slides (for the filmstrip rail).\n  - `slide` set (0-5): the focused-slide fast path — same render (the\n    full 6-slide canvas is still composited; cross-slide device bleed\n    means a slide can't render in isolation) but the response encodes\n    and returns ONLY that one slide's image, and `slides_meta` carries\n    just that slide's regions in image-local coordinates. This is the\n    hot interactive path for a focused-slide edit loop, so it's\n    rate-limited on its own, more generous window\n    (creative_preview.PREVIEW_SLIDE_RATE_LIMIT_PER_MIN) rather than\n    sharing the full-strip budget.\n\nNo credit check or deduction, no CreativeBatch/Job/CreativeAsset rows, and\nno vision calls (geometric placement only) — true for both response\nshapes. Serialized per workspace (one render in flight at a time)\nregardless of `slide`.","operationId":"preview_cpp_set_v1_apps__listing_id__cpp_sets_preview_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CppSetPreviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CppSetPreviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/ugc-avatars":{"get":{"tags":["creative-apps"],"summary":"Ugc Avatars","description":"The curated stock avatars and platform sizes a customer can choose from.\n\nStatic catalog (no auth needed beyond the router's) so the picker can render\ninstantly; the same allowlist gates what we'll actually render server-side.","operationId":"ugc_avatars_v1_ugc_avatars_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/ugc-characters":{"get":{"tags":["creative-apps"],"summary":"List Ugc Characters","description":"AI creators the customer can pick: shared presets + this workspace's own\ngenerated characters. Avatar IV drives the chosen one.","operationId":"list_ugc_characters_v1_ugc_characters_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/ugc-characters/generate":{"post":{"tags":["creative-apps"],"summary":"Generate Ugc Character","description":"Generate a new AI creator from a description (we rewrite it to our UGC\nstandards), cache it, and add it to the workspace's library. Free in beta;\ncapped per workspace.","operationId":"generate_ugc_character_v1_ugc_characters_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CharacterGenerate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/apps/{listing_id}/ugc-scripts":{"post":{"tags":["creative-apps"],"summary":"Ugc Scripts","description":"3 spoken UGC scripts mined from the app's reviews, sized to the target clip\nlength (7 / 15 / 30s) — the options the user picks from before generating a\ntalking-photo video. Free (no credits).","operationId":"ugc_scripts_v1_apps__listing_id__ugc_scripts_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}},{"name":"duration_s","in":"query","required":false,"schema":{"type":"integer","default":15,"title":"Duration S"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/ugc-voices":{"get":{"tags":["creative-apps"],"summary":"Ugc Voices","description":"Curated relaxed/conversational voices (with preview audio) the customer can\npick from when generating a UGC video. Free. (listing_id kept for path\nconsistency with the other UGC endpoints; the catalog is global.)","operationId":"ugc_voices_v1_apps__listing_id__ugc_voices_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/ugc":{"post":{"tags":["creative-apps"],"summary":"Create Ugc","description":"Generate a UGC video from a chosen script + one of: a `character` (our AI\ncreator → Avatar IV, the beta path), a curated stock `avatar`, or an uploaded\ncreator photo. At the selected platform size. Credit-metered; refunded on\nfailure.","operationId":"create_ugc_v1_apps__listing_id__ugc_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_ugc_v1_apps__listing_id__ugc_post"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batches":{"get":{"tags":["creative-batches"],"summary":"List Batches","description":"List the workspace's batches, newest first. Assets omitted — use the detail route.","operationId":"list_batches_v1_batches_get","security":[{"HTTPBearer":[]}],"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/BatchRead"},"title":"Response List Batches V1 Batches Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["creative-batches"],"summary":"Create Batch","description":"Create a render batch: validate inputs, debit credits, enqueue the job.","operationId":"create_batch_v1_batches_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/assets/recent":{"get":{"tags":["creative-batches"],"summary":"List Recent Assets","description":"Newest finished creatives across the whole workspace (recent-work\ngallery), with freshly-signed URLs. Only ``ready`` assets are returned.","operationId":"list_recent_assets_v1_assets_recent_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":12,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GalleryAssetRead"},"title":"Response List Recent Assets V1 Assets Recent Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batches/{batch_id}":{"get":{"tags":["creative-batches"],"summary":"Get Batch","description":"Batch status + all assets, with freshly re-signed asset URLs.","operationId":"get_batch_v1_batches__batch_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Batch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/batches/{batch_id}/download":{"get":{"tags":["creative-batches"],"summary":"Download Batch","description":"Stream a zip of every ready asset in the batch.","operationId":"download_batch_v1_batches__batch_id__download_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Batch Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/scene":{"post":{"tags":["asc-studio"],"summary":"Studio Scene","description":"AI themed-background scene for the Studio's Backdrop > AI scene tab\n(SPEC §3.4.4). Generates ONE low-res preview-quality image (capped at\nstudio_gen.SCENE_MAX_W, matching creative_preview's preview-panorama\ncap), blends the active theme's hexes into the prompt, and caches by\ncontent hash under studio-scenes/{workspace_id}/ — a repeat call with the\nidentical (prompt, w, h, theme) never re-pays for generation.\n\nNot credit-gated (composing is free; export is where credits get\ncharged, see studio_charge_export) — bounded only by a dedicated fal\nsub-limiter (studio_gen.FAL_STUDIO_RATE_LIMIT_PER_MIN/_DAY) shared with\nthe sprite endpoint below.","operationId":"studio_scene_v1_apps__listing_id__studio_scene_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioSceneRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioSceneResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/sprite":{"post":{"tags":["asc-studio"],"summary":"Studio Sprite","description":"AI sprite/character for the Studio's Sprites tab (SPEC §3.5). Requests\na plain background the client can key/composite freely, caches by\ncontent hash under studio-sprites/{workspace_id}/. Not credit-gated —\nsame dedicated fal sub-limiter as studio_scene.","operationId":"studio_sprite_v1_apps__listing_id__studio_sprite_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioSpriteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioSpriteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/direct":{"post":{"tags":["asc-studio"],"summary":"Studio Direct","description":"Auto-Direct: read the app's raw screens + store metadata in ONE vision\ncall and return an art-directed plan (order, claim headlines with an\naccent span, specific sublines, pop-out regions, palette, font, trust\nchips) that the client turns into ordinary editable Studio elements.\n\nFree like every other compose action (export is where credits are\ncharged), bounded by its own per-workspace limiter. SECURITY: the server\nonly fetches URLs that resolve to this listing's own uploaded screenshots\n(matched by GCS object key), so it can't be pointed at arbitrary hosts or\nanother workspace's files.","operationId":"studio_direct_v1_apps__listing_id__studio_direct_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioDirectRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioDirectResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/asset":{"get":{"tags":["asc-studio"],"summary":"Studio Asset","description":"Serve one of this workspace's Studio images through the API so the\nexport canvas can read its pixels. The browser can't: the assets bucket\nsends no CORS headers, and a cross-origin image taints the canvas. The\nAPI already has CORS for the dashboard.\n\nSECURITY: only this listing's uploaded screenshots and this workspace's\nown studio-scenes|studio-sprites|studio-sets objects. Anything else 404s,\nso it can't be used to read another workspace's files.","operationId":"studio_asset_v1_apps__listing_id__studio_asset_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}},{"name":"u","in":"query","required":true,"schema":{"type":"string","title":"U"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/photo":{"post":{"tags":["asc-studio"],"summary":"Studio Photo","description":"Auto-Direct lifestyle hero photo. Optionally crops the app's mascot\nfrom one of the listing's own screenshots and passes it as a reference so\nthe character appears in the photo. Free; shares the studio fal limiter.","operationId":"studio_photo_v1_apps__listing_id__studio_photo_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioPhotoRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioPhotoResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/studio/offer":{"get":{"tags":["asc-studio"],"summary":"Studio Offer","description":"This workspace's first-set offer: {state, expires_at?, price_cents, regular_cents}.","operationId":"studio_offer_v1_studio_offer_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Studio Offer V1 Studio Offer Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/studio/offer/start":{"post":{"tags":["asc-studio"],"summary":"Studio Offer Start","description":"Start the 10-minute clock (idempotent while it's running). 409 once the\noffer is expired, redeemed, or the workspace is ineligible.","operationId":"studio_offer_start_v1_studio_offer_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OfferStartRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Studio Offer Start V1 Studio Offer Start Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/apps/{listing_id}/studio/access":{"get":{"tags":["asc-studio"],"summary":"Studio Access","description":"What this workspace may do with a set: Studio (everything), this set\nunlocked (clean download + Quick Edit), and free unlocks remaining.","operationId":"studio_access_v1_apps__listing_id__studio_access_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}},{"name":"set_key","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Set Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioAccessResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/unlock":{"post":{"tags":["asc-studio"],"summary":"Studio Unlock","description":"Unlock one set for clean download. Order: Studio (nothing to do) →\nalready unlocked → a free unlock (consumed atomically) → $9.99 Stripe\nCheckout, whose webhook records the unlock (billing.handle_set_unlock_completed).\nWith offer=true the Checkout is the one-time $4.99 first-set offer — 409\nunless that offer is active right now.","operationId":"studio_unlock_v1_apps__listing_id__studio_unlock_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioUnlockRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioUnlockResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/charge-export":{"post":{"tags":["asc-studio"],"summary":"Studio Charge Export","description":"The export gate (pay-per-set model, 2026-10-03): clean PNGs are allowed\nwhen the workspace is on Studio or this set is unlocked. Nothing is\ncharged here any more — the $9.99 unlock or the subscription already paid.\n402 {needs: 'unlock'} otherwise, which the client turns into the unlock\ndialog.","operationId":"studio_charge_export_v1_apps__listing_id__studio_charge_export_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioChargeExportRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioChargeExportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/resign":{"post":{"tags":["asc-studio"],"summary":"Studio Resign","description":"Re-sign expired Studio asset URLs (AI scenes, sprites, archived set\nslides). Returns a {old_url: fresh_url} map; unknown or foreign URLs are\nsilently omitted rather than erroring, so a partial refresh still helps.\n\nGCS v4 signed URLs cap at 7 days and the Studio persists them in\nlocalStorage forever — without this, generated backdrops and sprites go\npermanently broken a week after creation (uploaded screenshots are covered\nseparately: get_app/list_apps re-sign uploaded_screenshots on every read).\n\nSECURITY: only re-signs objects under this workspace's own prefixes\n(studio-scenes|studio-sprites|studio-sets/{workspace_id}/…), so a caller\ncan never mint a URL for another workspace's assets.","operationId":"studio_resign_v1_apps__listing_id__studio_resign_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StudioResignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/sets":{"post":{"tags":["asc-studio"],"summary":"Studio Save Set","description":"Persist a just-exported Studio set so it shows in the dashboard gallery.\n\nCalled by the client AFTER charge-export + local downloads succeed — this\nendpoint is free (the export already paid) and non-critical: a failure\nhere never claws back a successful export, the set just isn't archived.\n\nCreates CreativeBatch(kind='studio_set', status='completed') + one ready\nCreativeAsset(kind='screenshot') per slide, uploaded to GCS under\nstudio-sets/{workspace}/{batch}/ — the existing per-app gallery endpoint\n(apps.py list_app_assets) then returns them with zero query changes.\nEach slide also gets the engine's small webp thumbnail (meta['thumb_path'])\nso gallery tiles + Home covers fetch ~30KB, not the multi-MB PNG.","operationId":"studio_save_set_v1_apps__listing_id__studio_sets_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_studio_save_set_v1_apps__listing_id__studio_sets_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/agent-sets/{set_key}":{"get":{"tags":["asc-studio"],"summary":"Studio Agent Set","description":"Open a set an agent designed (MCP) in the studio: the plan plus fresh\nURLs for its screenshots and photo, so the client composes it exactly\nlike one of its own Auto-Direct sets.","operationId":"studio_agent_set_v1_apps__listing_id__studio_agent_sets__set_key__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}},{"name":"set_key","in":"path","required":true,"schema":{"type":"string","title":"Set Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/asc/connection":{"get":{"tags":["asc-connect"],"summary":"Asc Connection Status","operationId":"asc_connection_status_v1_asc_connection_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AscConnectionStatus"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["asc-connect"],"summary":"Asc Connect","operationId":"asc_connect_v1_asc_connection_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AscConnectRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AscConnectionStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]},"delete":{"tags":["asc-connect"],"summary":"Asc Disconnect","operationId":"asc_disconnect_v1_asc_connection_delete","responses":{"204":{"description":"Successful Response"}},"security":[{"HTTPBearer":[]}]}},"/v1/apps/{listing_id}/studio/asc-target":{"get":{"tags":["asc-connect"],"summary":"Asc Target","description":"What an upload would touch — shown in the confirm step before anything\nis written.","operationId":"asc_target_v1_apps__listing_id__studio_asc_target_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AscTarget"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/apps/{listing_id}/studio/asc-upload":{"post":{"tags":["asc-connect"],"summary":"Asc Upload","description":"Replace this locale's screenshots for one device size in the app's\neditable version with the uploaded set. Never submits for review.","operationId":"asc_upload_v1_apps__listing_id__studio_asc_upload_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_asc_upload_v1_apps__listing_id__studio_asc_upload_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AscUploadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/api-keys":{"get":{"tags":["api-keys"],"summary":"List Keys","operationId":"list_keys_v1_api_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ApiKeyRead"},"type":"array","title":"Response List Keys V1 Api Keys Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["api-keys"],"summary":"Create Key","operationId":"create_key_v1_api_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/api-keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke Key","operationId":"revoke_key_v1_api_keys__key_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/agent-upload/{token}":{"post":{"tags":["agent-upload"],"summary":"Agent Upload","operationId":"agent_upload_v1_agent_upload__token__post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_agent_upload_v1_agent_upload__token__post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/render/health":{"get":{"tags":["agent-upload"],"summary":"Render Health","description":"Deploy check for server-side rendering: is a browser installed, and\nwhich /render page will it open. No customer data involved.","operationId":"render_health_v1_render_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/apps/{listing_id}/cinematic":{"post":{"tags":["cinematic"],"summary":"Create Campaign","description":"Buy a Strategy Blueprint: credit-check + debit, create the campaign, enqueue.","operationId":"create_campaign_v1_apps__listing_id__cinematic_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CinematicCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["cinematic"],"summary":"Get Latest Campaign","description":"The most recent cinematic campaign for an app (mount hydration so a tab\nswitch / refresh never loses — and re-charges for — a paid campaign). 204 if none.","operationId":"get_latest_campaign_v1_apps__listing_id__cinematic_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"listing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Listing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cinematic/{campaign_id}":{"get":{"tags":["cinematic"],"summary":"Get Campaign","description":"Campaign status + the blueprint (with freshly-signed still/static URLs).","operationId":"get_campaign_v1_cinematic__campaign_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cinematic/{campaign_id}/steer":{"post":{"tags":["cinematic"],"summary":"Steer Campaign","description":"Correct the read and regenerate the blueprint (free iteration on the buy).","operationId":"steer_campaign_v1_cinematic__campaign_id__steer_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SteerUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cinematic/{campaign_id}/storyboard":{"post":{"tags":["cinematic"],"summary":"Generate Storyboard Endpoint","description":"Render the storyboard frames (free — rolls into the blueprint purchase).","operationId":"generate_storyboard_endpoint_v1_cinematic__campaign_id__storyboard_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cinematic/{campaign_id}/video":{"post":{"tags":["cinematic"],"summary":"Render Video Endpoint","description":"Render the cinematic video (credit-gated; refunded on failure).","operationId":"render_video_endpoint_v1_cinematic__campaign_id__video_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/cinematic/{campaign_id}/brief":{"get":{"tags":["cinematic"],"summary":"Get Brief","description":"The rendered HTML marketing-direction brief.","operationId":"get_brief_v1_cinematic__campaign_id__brief_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/kit":{"post":{"tags":["creative-kit"],"summary":"Create Kit","description":"Create a free-kit batch from an App Store URL. No auth, watermarked output.","operationId":"create_kit_v1_kit_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KitCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KitCreateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/kit/{kit_id}":{"get":{"tags":["creative-kit"],"summary":"Get Kit","description":"Poll a kit by id + public token. Returns scorecard + assets when done.","operationId":"get_kit_v1_kit__kit_id__get","parameters":[{"name":"kit_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Kit Id"}},{"name":"token","in":"query","required":true,"schema":{"type":"string","minLength":8,"title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KitStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/assets/{path}":{"get":{"tags":["assets"],"summary":"Get Asset","description":"Serve a rendered asset from ./var/assets/, with path-traversal guard.","operationId":"get_asset_v1_assets__path__get","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/feedback":{"post":{"tags":["feedback"],"summary":"Submit Feedback","description":"Record a piece of feedback from the signed-in user.","operationId":"submit_feedback_v1_feedback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Submit Feedback V1 Feedback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/events":{"post":{"tags":["events"],"summary":"Track Event","operationId":"track_event_v1_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventCreate"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/internal/insights":{"get":{"tags":["internal"],"summary":"Insights","operationId":"insights_v1_internal_insights_get","parameters":[{"name":"x-insights-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Insights-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Insights V1 Internal Insights Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/internal/feedback/{feedback_id}":{"post":{"tags":["internal"],"summary":"Triage Feedback","description":"Update a feedback row's status / note; notified=true stamps notified_at\n(false clears it).","operationId":"triage_feedback_v1_internal_feedback__feedback_id__post","parameters":[{"name":"feedback_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Feedback Id"}},{"name":"x-insights-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Insights-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FeedbackTriage"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Triage Feedback V1 Internal Feedback  Feedback Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/overview":{"get":{"tags":["owner"],"summary":"Overview","description":"Founder dashboard summary.","operationId":"overview_v1_owner_overview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Overview V1 Owner Overview Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/owner/feedback":{"get":{"tags":["owner"],"summary":"List Feedback","description":"Recent in-product feedback + counts by kind, for the founder dashboard.","operationId":"list_feedback_v1_owner_feedback_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response List Feedback V1 Owner Feedback Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/credits/topup":{"post":{"tags":["owner"],"summary":"Credits Topup","description":"Owner self-serve credit top-up — brings the owner's own workspace up to\n`to` (default 100). Additive (never lowers a higher balance), logged to the\nledger as a manual adjustment. For dogfooding without SSHing the DB.","operationId":"credits_topup_v1_owner_credits_topup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopUpRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Credits Topup V1 Owner Credits Topup Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/v1/owner/leads.csv":{"get":{"tags":["owner"],"summary":"Leads Csv","description":"Export the captured email list as CSV.","operationId":"leads_csv_v1_owner_leads_csv_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50000,"minimum":1,"default":5000,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/backfill-ugc-posters":{"post":{"tags":["owner"],"summary":"Backfill Ugc Posters","description":"One-off (owner-only): generate mid-frame poster JPGs for existing UGC\nvideos that don't have one yet. Runs in-container (ffmpeg + DB both here);\ncall repeatedly in small batches until ``remaining`` is 0. Idempotent.","operationId":"backfill_ugc_posters_v1_owner_backfill_ugc_posters_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/owner/backfill-thumbnails":{"post":{"tags":["owner"],"summary":"Backfill Thumbnails","description":"One-off (owner-only): generate small webp thumbnails for existing image\nassets (static/screenshot/scorecard) missing one, so gallery tiles fetch\n~30KB instead of the multi-MB original. In-container; call in batches until\n``remaining`` is 0. Idempotent.","operationId":"backfill_thumbnails_v1_owner_backfill_thumbnails_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/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 Post","operationId":"mcp_post_mcp_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"delete":{"tags":["mcp"],"summary":"Mcp Delete","operationId":"mcp_delete_mcp_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"ApiKeyCreate":{"properties":{"name":{"type":"string","maxLength":80,"minLength":1,"title":"Name","default":"My agent"}},"type":"object","title":"ApiKeyCreate"},"ApiKeyCreated":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"prefix":{"type":"string","title":"Prefix"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"},"key":{"type":"string","title":"Key"}},"type":"object","required":["id","name","prefix","created_at","last_used_at","key"],"title":"ApiKeyCreated"},"ApiKeyRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"prefix":{"type":"string","title":"Prefix"},"created_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Created At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["id","name","prefix","created_at","last_used_at"],"title":"ApiKeyRead"},"AppCreate":{"properties":{"app_store_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Store Url","description":"App Store URL or bare numeric Apple app id (live apps)"},"unreleased":{"type":"boolean","title":"Unreleased","description":"App is not in the App Store yet","default":false},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name","description":"App name (unreleased apps)"},"category":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Category","description":"Category (unreleased apps)"}},"type":"object","title":"AppCreate","description":"Add an app two ways:\n• Live: pass `app_store_url` → we ingest store metadata/reviews.\n• Not live yet: pass `unreleased=True` + `name` (+ optional `category`) →\n  a draft listing you can upload screenshots to and run the ASC/creative\n  pipeline against before it's in the store."},"AppCreateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"status":{"type":"string","title":"Status"},"job_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Job Id"}},"type":"object","required":["id","status"],"title":"AppCreateResponse"},"AppListingRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"workspace_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Workspace Id"},"apple_app_id":{"type":"string","title":"Apple App Id"},"bundle_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bundle Id"},"name":{"type":"string","title":"Name"},"subtitle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtitle"},"category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Category"},"icon_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Icon Url"},"screenshot_urls":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Screenshot Urls"},"uploaded_screenshots":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Uploaded Screenshots"},"brand_tokens":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Brand Tokens"},"review_summary":{"anyOf":[{"$ref":"#/components/schemas/ReviewSummary"},{"type":"null"}]},"concepts_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Concepts Count"},"cover_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cover Url"},"unreleased":{"type":"boolean","title":"Unreleased","default":false},"status":{"type":"string","title":"Status"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"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","apple_app_id","bundle_id","name","subtitle","category","icon_url","screenshot_urls","brand_tokens","status","error","created_at","updated_at"],"title":"AppListingRead"},"AscConnectRequest":{"properties":{"issuer_id":{"type":"string","maxLength":64,"title":"Issuer Id"},"key_id":{"type":"string","maxLength":32,"title":"Key Id"},"private_key":{"type":"string","maxLength":4000,"title":"Private Key"}},"type":"object","required":["issuer_id","key_id","private_key"],"title":"AscConnectRequest"},"AscConnectionStatus":{"properties":{"connected":{"type":"boolean","title":"Connected"},"key_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key Id"},"issuer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Issuer Id"},"connected_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Connected At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["connected"],"title":"AscConnectionStatus"},"AscTarget":{"properties":{"app_name":{"type":"string","title":"App Name"},"asc_app_id":{"type":"string","title":"Asc App Id"},"version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version"},"version_state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Version State"},"needs_new_version":{"type":"boolean","title":"Needs New Version","default":false},"next_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Version"}},"type":"object","required":["app_name","asc_app_id"],"title":"AscTarget"},"AscTheme":{"properties":{"key":{"type":"string","title":"Key"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description","default":""},"prompt":{"type":"string","title":"Prompt"}},"type":"object","required":["key","name","prompt"],"title":"AscTheme"},"AscThemesRequest":{"properties":{"hint":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Hint"},"count":{"type":"integer","maximum":6.0,"minimum":2.0,"title":"Count","default":4}},"type":"object","title":"AscThemesRequest"},"AscThemesResponse":{"properties":{"themes":{"items":{"$ref":"#/components/schemas/AscTheme"},"type":"array","title":"Themes"}},"type":"object","required":["themes"],"title":"AscThemesResponse"},"AscUploadResponse":{"properties":{"version":{"type":"string","title":"Version"},"created_version":{"type":"boolean","title":"Created Version"},"locale":{"type":"string","title":"Locale"},"display_type":{"type":"string","title":"Display Type"},"replaced":{"type":"integer","title":"Replaced"},"uploaded":{"type":"integer","title":"Uploaded"},"processing":{"type":"integer","title":"Processing"},"failed":{"type":"integer","title":"Failed"}},"type":"object","required":["version","created_version","locale","display_type","replaced","uploaded","processing","failed"],"title":"AscUploadResponse"},"AssetRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"batch_id":{"type":"string","format":"uuid","title":"Batch Id"},"concept_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Concept Id"},"format_key":{"type":"string","title":"Format Key"},"kind":{"type":"string","title":"Kind"},"storage_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Storage Path"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Width"},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Height"},"bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bytes"},"duration_s":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration S"},"meta":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Meta"},"poster_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Poster Url"},"thumb_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumb Url"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","batch_id","concept_id","format_key","kind","storage_path","url","width","height","duration_s","meta","status","created_at"],"title":"AssetRead"},"BatchCreate":{"properties":{"app_listing_id":{"type":"string","format":"uuid","title":"App Listing Id"},"concept_ids":{"items":{"type":"string","format":"uuid"},"type":"array","minItems":1,"title":"Concept Ids"},"formats":{"items":{"type":"string"},"type":"array","title":"Formats"},"kinds":{"items":{"type":"string"},"type":"array","title":"Kinds","description":"Extra per-concept render kinds: gen_video, ugc"}},"type":"object","required":["app_listing_id","concept_ids"],"title":"BatchCreate"},"BatchCreateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"status":{"type":"string","title":"Status"},"credits_cost":{"type":"integer","title":"Credits Cost"},"job_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Job Id"}},"type":"object","required":["id","status","credits_cost"],"title":"BatchCreateResponse"},"BatchRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"workspace_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Workspace Id"},"app_listing_id":{"type":"string","format":"uuid","title":"App Listing Id"},"kind":{"type":"string","title":"Kind"},"formats":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Formats"},"concept_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Concept Ids"},"status":{"type":"string","title":"Status"},"credits_cost":{"type":"integer","title":"Credits Cost"},"watermark":{"type":"boolean","title":"Watermark"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"assets":{"items":{"$ref":"#/components/schemas/AssetRead"},"type":"array","title":"Assets"},"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","app_listing_id","kind","formats","concept_ids","status","credits_cost","watermark","error","created_at","updated_at"],"title":"BatchRead"},"Body_agent_upload_v1_agent_upload__token__post":{"properties":{"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files"}},"type":"object","required":["files"],"title":"Body_agent_upload_v1_agent_upload__token__post"},"Body_asc_upload_v1_apps__listing_id__studio_asc_upload_post":{"properties":{"set_key":{"type":"string","maxLength":128,"title":"Set Key"},"locale":{"type":"string","maxLength":16,"title":"Locale","default":"en-US"},"create_version":{"type":"boolean","title":"Create Version","default":false},"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files"}},"type":"object","required":["set_key","files"],"title":"Body_asc_upload_v1_apps__listing_id__studio_asc_upload_post"},"Body_create_ugc_v1_apps__listing_id__ugc_post":{"properties":{"script":{"type":"string","title":"Script"},"duration_s":{"type":"integer","title":"Duration S","default":15},"character":{"type":"string","title":"Character","default":""},"avatar":{"type":"string","title":"Avatar","default":""},"voice_gender":{"type":"string","title":"Voice Gender","default":"female"},"voice":{"type":"string","title":"Voice","default":""},"platform":{"type":"string","title":"Platform","default":"tiktok"},"image":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"Image"}},"type":"object","required":["script"],"title":"Body_create_ugc_v1_apps__listing_id__ugc_post"},"Body_studio_save_set_v1_apps__listing_id__studio_sets_post":{"properties":{"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files"},"project_name":{"type":"string","title":"Project Name","default":"Untitled set"},"device_key":{"type":"string","title":"Device Key","default":"69"},"width":{"type":"integer","title":"Width","default":0},"height":{"type":"integer","title":"Height","default":0}},"type":"object","required":["files"],"title":"Body_studio_save_set_v1_apps__listing_id__studio_sets_post"},"Body_upload_screenshots_v1_apps__listing_id__screenshots_post":{"properties":{"files":{"items":{"type":"string","format":"binary"},"type":"array","title":"Files"}},"type":"object","required":["files"],"title":"Body_upload_screenshots_v1_apps__listing_id__screenshots_post"},"BrandCreate":{"properties":{"name":{"type":"string","title":"Name"},"niche":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Niche"}},"type":"object","required":["name"],"title":"BrandCreate"},"BrandRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"workspace_id":{"type":"string","format":"uuid","title":"Workspace Id"},"name":{"type":"string","title":"Name"},"niche":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Niche"},"soul_config":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Soul Config"},"brand_kit":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Brand Kit"},"platforms":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Platforms"},"content_pillars":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Content Pillars"},"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","name","niche","soul_config","brand_kit","platforms","content_pillars","created_at","updated_at"],"title":"BrandRead"},"BreakerStatus":{"properties":{"service":{"type":"string","title":"Service"},"state":{"type":"string","title":"State"},"failure_count":{"type":"integer","title":"Failure Count"},"failure_threshold":{"type":"integer","title":"Failure Threshold"},"can_execute":{"type":"boolean","title":"Can Execute"}},"type":"object","required":["service","state","failure_count","failure_threshold","can_execute"],"title":"BreakerStatus"},"CallbackRequest":{"properties":{"code":{"type":"string","title":"Code","description":"Authorization code from the platform"},"state":{"type":"string","title":"State","description":"CSRF state to verify"},"brand_id":{"type":"string","format":"uuid","title":"Brand Id","description":"Brand being connected"},"platform":{"type":"string","title":"Platform","description":"Platform being connected"},"redirect_uri":{"type":"string","title":"Redirect Uri","description":"Same redirect_uri used in connect"}},"type":"object","required":["code","state","brand_id","platform","redirect_uri"],"title":"CallbackRequest","description":"OAuth callback parameters (from platform redirect)."},"CallbackResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"platform":{"type":"string","title":"Platform"},"account_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Username"},"message":{"type":"string","title":"Message"}},"type":"object","required":["success","platform","message"],"title":"CallbackResponse","description":"Result of completing OAuth flow."},"CampaignCreate":{"properties":{"brand_id":{"type":"string","format":"uuid","title":"Brand Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"integer","maximum":3.0,"minimum":1.0,"title":"Mode","description":"Content mode: 1=customer ideas, 2=video upload, 3=full AI"},"autonomy":{"type":"string","title":"Autonomy","description":"Autonomy level: always_ask, ask_for_expensive, full_auto","default":"always_ask"},"cadence":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Cadence","description":"Scheduling config: {days: ['mon','wed','fri'], time: '09:00', timezone: 'US/Eastern'}"},"config":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Config","description":"Campaign-specific config: content type, platforms, templates"}},"type":"object","required":["brand_id","name","mode"],"title":"CampaignCreate","description":"Schema for creating a new campaign."},"CampaignListResponse":{"properties":{"campaigns":{"items":{"$ref":"#/components/schemas/CampaignRead"},"type":"array","title":"Campaigns"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["campaigns","total","limit","offset"],"title":"CampaignListResponse","description":"Paginated list response for campaigns."},"CampaignRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"brand_id":{"type":"string","format":"uuid","title":"Brand Id"},"name":{"type":"string","title":"Name"},"mode":{"type":"integer","title":"Mode"},"cadence":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Cadence"},"autonomy":{"type":"string","title":"Autonomy"},"status":{"type":"string","title":"Status"},"next_run_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Next Run At"},"config":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Config"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","brand_id","name","mode","cadence","autonomy","status","next_run_at","config","created_at","updated_at"],"title":"CampaignRead","description":"Campaign details for API responses."},"CampaignStatusChange":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"status":{"type":"string","title":"Status"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"message":{"type":"string","title":"Message"}},"type":"object","required":["id","status","updated_at","message"],"title":"CampaignStatusChange","description":"Response for status change operations (pause/resume)."},"CampaignUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"mode":{"anyOf":[{"type":"integer","maximum":3.0,"minimum":1.0},{"type":"null"}],"title":"Mode"},"autonomy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Autonomy"},"cadence":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Cadence"},"config":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Config"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},"type":"object","title":"CampaignUpdate","description":"Schema for updating an existing campaign."},"CharacterGenerate":{"properties":{"prompt":{"type":"string","maxLength":600,"minLength":1,"title":"Prompt"},"gender":{"type":"string","title":"Gender","default":"female"},"name":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Name"}},"type":"object","required":["prompt"],"title":"CharacterGenerate"},"ChatMessage":{"properties":{"role":{"type":"string","title":"Role","description":"Message role: 'user' or 'assistant'"},"content":{"type":"string","title":"Content","description":"Message content"},"timestamp":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp","description":"When the message was sent"},"tool_calls":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Tool Calls","description":"Tool calls made during this message (assistant only)"}},"type":"object","required":["role","content"],"title":"ChatMessage","description":"A single message in a chat session."},"ChatRequest":{"properties":{"brand_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Id","description":"Legacy, ignored"},"message":{"type":"string","maxLength":10000,"minLength":1,"title":"Message","description":"User message"},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Existing session UUID to continue. Omit for new session."}},"type":"object","required":["message"],"title":"ChatRequest","description":"Request to send a message to Jr.\n\nbrand_id is a legacy AI-COO field — accepted and ignored so old clients\ndon't break; Jr.'s context now comes from the workspace's apps.","examples":[{"message":"Which hook should I lead with for TikTok?"}]},"ChatSessionDetail":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"user_uid":{"type":"string","title":"User Uid"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"messages":{"items":{"$ref":"#/components/schemas/ChatMessage"},"type":"array","title":"Messages","default":[]},"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","user_uid","created_at","updated_at"],"title":"ChatSessionDetail","description":"Full chat session with messages."},"ChatSessionRead":{"properties":{"id":{"type":"string","title":"Id"},"workspace_id":{"type":"string","title":"Workspace Id"},"user_uid":{"type":"string","title":"User Uid"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"message_count":{"type":"integer","title":"Message Count","default":0},"last_message_preview":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Message Preview"},"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","user_uid","created_at","updated_at"],"title":"ChatSessionRead","description":"Read-only view of a chat session."},"ChipRegion":{"properties":{"x0":{"type":"number","maximum":1.0,"minimum":0.0,"title":"X0"},"y0":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Y0"},"x1":{"type":"number","maximum":1.0,"minimum":0.0,"title":"X1"},"y1":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Y1"},"label":{"anyOf":[{"type":"string","maxLength":30},{"type":"null"}],"title":"Label"}},"type":"object","required":["x0","y0","x1","y1"],"title":"ChipRegion","description":"A showcase chip's explicit source rect, with an optional user label\noverride (falls back to the vision/fallback-derived label when omitted)."},"CinematicCreate":{"properties":{"tier":{"type":"string","pattern":"^(standard|premium)$","title":"Tier","default":"standard"},"format":{"type":"string","pattern":"^(9x16|1x1|16x9)$","title":"Format","default":"9x16"},"length_s":{"type":"integer","title":"Length S","default":15},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"steer":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Steer"}},"type":"object","title":"CinematicCreate"},"ConceptGenerateRequest":{"properties":{"count":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Count","default":8},"competitor_app_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Competitor App Ids"}},"type":"object","title":"ConceptGenerateRequest"},"ConceptGenerateResponse":{"properties":{"job_id":{"type":"string","format":"uuid","title":"Job Id"},"status":{"type":"string","title":"Status"}},"type":"object","required":["job_id","status"],"title":"ConceptGenerateResponse"},"ConceptRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"app_listing_id":{"type":"string","format":"uuid","title":"App Listing Id"},"workspace_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Workspace Id"},"hook":{"type":"string","title":"Hook"},"kicker":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kicker"},"claim":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Claim"},"subtext":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtext"},"cta":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cta"},"angle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Angle"},"visual_scheme":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Visual Scheme"},"policy_flags":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Policy Flags"},"source":{"type":"string","title":"Source"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","app_listing_id","workspace_id","hook","kicker","claim","subtext","cta","angle","visual_scheme","policy_flags","source","status","created_at","updated_at"],"title":"ConceptRead"},"ConceptUpdate":{"properties":{"hook":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hook"},"kicker":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kicker"},"claim":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Claim"},"subtext":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Subtext"},"cta":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cta"},"angle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Angle"},"visual_scheme":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Visual Scheme"},"status":{"anyOf":[{"type":"string","pattern":"^(draft|approved|archived)$"},{"type":"null"}],"title":"Status"}},"type":"object","title":"ConceptUpdate"},"ConnectRequest":{"properties":{"brand_id":{"type":"string","format":"uuid","title":"Brand Id","description":"Brand to connect the platform to"},"platform":{"type":"string","title":"Platform","description":"Platform to connect: x, youtube, pinterest"},"redirect_uri":{"type":"string","title":"Redirect Uri","description":"Frontend URL to redirect after OAuth completes"}},"type":"object","required":["brand_id","platform","redirect_uri"],"title":"ConnectRequest","description":"Request to initiate OAuth flow for a platform."},"ConnectResponse":{"properties":{"authorization_url":{"type":"string","title":"Authorization Url"},"state":{"type":"string","title":"State"}},"type":"object","required":["authorization_url","state"],"title":"ConnectResponse","description":"OAuth redirect URL for the user to authorize."},"ContentCreate":{"properties":{"brand_id":{"type":"string","format":"uuid","title":"Brand Id"},"content_type":{"type":"string","title":"Content Type","description":"Type of content: text, image, video, thread, carousel, pin"},"platform":{"type":"string","title":"Platform","description":"Target platform: x, youtube, pinterest, instagram, instagram_reels"},"body":{"type":"object","title":"Body","description":"Platform-specific content body with text, media_urls, hashtags, etc."},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled At","description":"When to publish (optional)"}},"type":"object","required":["brand_id","content_type","platform","body"],"title":"ContentCreate","description":"Request model for creating content (draft)."},"ContentPublishRequest":{"properties":{"mode":{"type":"string","title":"Mode","description":"Content creation mode: mode_1, mode_2, or mode_3"}},"type":"object","required":["mode"],"title":"ContentPublishRequest","description":"Request model for publishing content (triggers credit deduction)."},"ContentRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"run_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Run Id"},"brand_id":{"type":"string","format":"uuid","title":"Brand Id"},"content_type":{"type":"string","title":"Content Type"},"platform":{"type":"string","title":"Platform"},"body":{"type":"object","title":"Body"},"status":{"type":"string","title":"Status"},"platform_post_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Post Id"},"rejection_feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rejection Feedback"},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled At"},"posted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Posted At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","run_id","brand_id","content_type","platform","body","status","platform_post_id","rejection_feedback","scheduled_at","posted_at","created_at","updated_at"],"title":"ContentRead","description":"Full content item response model."},"ContentStats":{"properties":{"total":{"type":"integer","title":"Total"},"by_status":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Status","description":"Count of content items by status (draft, pending_approval, etc.)"},"by_platform":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Platform","description":"Count of content items by platform (x, youtube, etc.)"},"posted_count":{"type":"integer","title":"Posted Count","description":"Total number of successfully posted items","default":0},"posted_today":{"type":"integer","title":"Posted Today","description":"Number of items posted today","default":0}},"type":"object","required":["total"],"title":"ContentStats","description":"Aggregate statistics for content in a workspace."},"ContentUpdate":{"properties":{"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"body":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Body"},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled At"},"rejection_feedback":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rejection Feedback"}},"type":"object","title":"ContentUpdate","description":"Request model for updating content."},"CppSetCreate":{"properties":{"concept_ids":{"items":{"type":"string","format":"uuid"},"type":"array","minItems":1,"title":"Concept Ids"},"device":{"type":"string","pattern":"^(69|65)$","title":"Device","default":"69"},"theme_name":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Theme Name"},"theme_prompt":{"anyOf":[{"type":"string","maxLength":600},{"type":"null"}],"title":"Theme Prompt"},"slides":{"anyOf":[{"items":{"$ref":"#/components/schemas/CppSlide"},"type":"array","maxItems":6},{"type":"null"}],"title":"Slides"},"layout":{"type":"string","pattern":"^(classic|popout|momentum|zoom|showcase)$","title":"Layout","default":"popout"}},"type":"object","required":["concept_ids"],"title":"CppSetCreate"},"CppSetPreviewRequest":{"properties":{"device":{"type":"string","pattern":"^(69|65)$","title":"Device","default":"69"},"layout":{"type":"string","pattern":"^(classic|popout|momentum|zoom|showcase)$","title":"Layout","default":"popout"},"theme_prompt":{"anyOf":[{"type":"string","maxLength":600},{"type":"null"}],"title":"Theme Prompt"},"theme_image_key":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Theme Image Key"},"slides":{"anyOf":[{"items":{"$ref":"#/components/schemas/CppSlide"},"type":"array","maxItems":6},{"type":"null"}],"title":"Slides"},"slide":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":0.0},{"type":"null"}],"title":"Slide"},"scale":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Scale"}},"type":"object","title":"CppSetPreviewRequest","description":"Free, fast, low-res live preview of the CPP set builder — no credits,\nno persisted rows, no vision calls. Mirrors CppSetCreate's shape for the\nfields the preview actually varies.\n\n`slide`: when set, this is a FOCUSED-SLIDE refresh — the render still\ncomposites the full 6-slide canvas (cross-slide device bleed means a\nsingle slide can't be rendered in isolation: bridge/tilted devices on\nslide i can paint into slide i+1's crop region — see\ncreative_render.render_panoramic_slides), but the response encodes and\nreturns ONLY that one slide's image instead of the full 6-up strip. This\nis the hot interactive path (every headline/layout tweak while a slide is\nfocused) — see CppSetPreviewResponse.slide / .slides_meta for the\nsingle-slide response contract, and creative_preview's\nPREVIEW_SLIDE_RATE_LIMIT_PER_MIN for its more generous rate-limit window.\nOmit (null) for the normal full-strip render (all 6 slides, used for the\nfilmstrip rail).\n\n`scale`: optional render scale, clamped to {0.25, 0.4}. Default 0.25\n(330x717 @ 69\"). 0.4 (528x1147 @ 69\") renders a crisper focused slide —\nintended for use together with `slide`, though it's accepted either way."},"CppSetPreviewResponse":{"properties":{"strip":{"type":"string","title":"Strip"},"slide_w":{"type":"integer","title":"Slide W"},"slide_h":{"type":"integer","title":"Slide H"},"theme_image_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Theme Image Key"},"scene_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scene Status"},"slides_meta":{"anyOf":[{"items":{"$ref":"#/components/schemas/SlideMeta"},"type":"array"},{"type":"null"}],"title":"Slides Meta"},"slide":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Slide"}},"type":"object","required":["strip","slide_w","slide_h"],"title":"CppSetPreviewResponse"},"CppSlide":{"properties":{"shot":{"anyOf":[{"type":"integer","maximum":19.0,"minimum":0.0},{"type":"null"}],"title":"Shot"},"headline":{"type":"string","maxLength":80,"title":"Headline","default":""},"focus":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Focus"},"region":{"anyOf":[{"$ref":"#/components/schemas/SlideRegionRect"},{"type":"null"}]},"chip_regions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ChipRegion"},"type":"array","maxItems":3},{"type":"null"}],"title":"Chip Regions"}},"type":"object","title":"CppSlide","description":"One slide's user choices in the set builder: which uploaded screenshot (index\ninto the pool, or null) and the editable headline. Slide 0's screenshot is the\n45°-tilted hero that bridges slides 1-2; slide 1 carries no device of its own.\n\n`focus` is an optional user-named feature/element (e.g. \"the Next button\")\nthat Claude vision should pixel-locate on this slide's screenshot instead of\nderiving the feature claim from the headline/concept — popout/zoom layouts\nonly; ignored for classic/momentum, which draw no callouts.\n\n`region` is an explicit PRIMARY source-region override (zoom source /\npopout source / showcase card region) in screenshot fractions — when set,\nthe renderer skips vision entirely for that slide's primary role and uses\nthis rect exactly. `chip_regions` (showcase only, max 3) does the same for\nindividual chip anchors."},"CreditBalance":{"properties":{"balance":{"type":"integer","title":"Balance","description":"Credits remaining in current billing period","example":72},"total":{"type":"integer","title":"Total","description":"Total credits allocated for this billing period","example":100},"plan":{"type":"string","title":"Plan","description":"Current plan tier (free | pro | legacy builder/studio variants)","example":"pro"},"warning_level":{"type":"string","pattern":"^(normal|low|depleted)$","title":"Warning Level","description":"Balance warning level","example":"normal"},"video_used":{"type":"integer","title":"Video Used","description":"Videos created this month","example":2},"video_cap":{"type":"integer","title":"Video Cap","description":"Total videos allowed this month","example":100},"strategy_sessions_used":{"type":"integer","title":"Strategy Sessions Used","description":"Strategy sessions used this month","example":0},"strategy_sessions_included":{"type":"integer","title":"Strategy Sessions Included","description":"Strategy sessions included in plan","example":0},"next_reset_at":{"type":"string","format":"date-time","title":"Next Reset At","description":"When credits reset (monthly)","example":"2026-05-07T08:30:00Z"},"free_credits":{"type":"integer","title":"Free Credits","description":"Free bucket (tops up monthly, no rollover)","default":0},"paid_credits":{"type":"integer","title":"Paid Credits","description":"Purchased/sub bucket (rolls over)","default":0},"free_credits_reset_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Free Credits Reset At","description":"When the free bucket next tops up"}},"type":"object","required":["balance","total","plan","warning_level","video_used","video_cap","strategy_sessions_used","strategy_sessions_included","next_reset_at"],"title":"CreditBalance","description":"Current credit balance and tier information.","example":{"balance":72,"next_reset_at":"2026-05-07T08:30:00Z","plan":"builder","strategy_sessions_included":0,"strategy_sessions_used":0,"total":100,"video_cap":100,"video_used":2,"warning_level":"normal"}},"CreditCheckRequest":{"properties":{"action":{"type":"string","title":"Action","description":"The action being performed (e.g., 'mode_1_text', 'mode_3_video')","examples":["mode_1_text"]},"content_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content Type","description":"Optional content type for context","examples":["text","video"]}},"type":"object","required":["action"],"title":"CreditCheckRequest","description":"Request body for POST /v1/credits/check.","example":{"action":"mode_1_video","content_type":"video"}},"CreditCheckResult":{"properties":{"has_sufficient":{"type":"boolean","title":"Has Sufficient","description":"Whether workspace has enough credits","example":true},"current_balance":{"type":"integer","title":"Current Balance","description":"Current credit balance","example":200},"required":{"type":"integer","title":"Required","description":"Credits required for operation","example":6},"warning_level":{"type":"string","pattern":"^(normal|low|depleted)$","title":"Warning Level","description":"Current balance warning","example":"normal"}},"type":"object","required":["has_sufficient","current_balance","required","warning_level"],"title":"CreditCheckResult","description":"Result of pre-flight credit check.","example":{"current_balance":200,"has_sufficient":true,"required":6,"warning_level":"normal"}},"CreditDeduction":{"properties":{"id":{"type":"string","title":"Id","description":"Ledger entry ID","example":"550e8400-e29b-41d4-a716-446655440000"},"amount":{"type":"integer","title":"Amount","description":"Credits deducted (absolute value, positive number)","example":6},"reason":{"type":"string","title":"Reason","description":"Reason for deduction","example":"mode_1_video"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description","description":"Additional context","example":"Brand content for @acme"},"balance_after":{"type":"integer","title":"Balance After","description":"Balance after this deduction","example":144},"created_at":{"type":"string","format":"date-time","title":"Created At","description":"When this transaction occurred","example":"2026-04-07T10:30:00Z"}},"type":"object","required":["id","amount","reason","balance_after","created_at"],"title":"CreditDeduction","description":"A single credit ledger entry (deduction).","example":{"amount":6,"balance_after":144,"created_at":"2026-04-07T10:30:00Z","description":"Brand content for @acme","id":"550e8400-e29b-41d4-a716-446655440000","reason":"mode_1_video"}},"CreditHistory":{"properties":{"items":{"items":{"$ref":"#/components/schemas/CreditDeduction"},"type":"array","title":"Items","description":"Ledger entries for this page"},"total_count":{"type":"integer","title":"Total Count","description":"Total ledger entries across all pages","example":42},"has_more":{"type":"boolean","title":"Has More","description":"Whether there are more pages","example":false}},"type":"object","required":["items","total_count","has_more"],"title":"CreditHistory","description":"Paginated credit ledger history.","example":{"has_more":true,"items":[{"amount":6,"balance_after":144,"created_at":"2026-04-07T10:30:00Z","description":"Brand content for @acme","id":"550e8400-e29b-41d4-a716-446655440000","reason":"mode_1_video"}],"total_count":42}},"DispatchRunRequest":{"properties":{"brand_id":{"type":"string","title":"Brand Id","description":"Brand UUID"},"mode":{"type":"string","title":"Mode","description":"Content mode: 'mode_1' (customer idea), 'mode_2' (video upload), 'mode_3' (full AI)"},"content_type":{"type":"string","title":"Content Type","description":"Content type: 'text' or 'video'","default":"text"},"idea":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idea","description":"Customer's content idea (required for mode_1)"},"video_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Url","description":"URL of uploaded video (required for mode_2)"},"campaign_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Id","description":"Campaign UUID if this run is part of a campaign"},"platforms":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Platforms","description":"Target platforms: ['x', 'youtube', 'pinterest']. Defaults to all connected."}},"type":"object","required":["brand_id","mode"],"title":"DispatchRunRequest","description":"Request to enqueue a content pipeline run.","examples":[{"brand_id":"550e8400-e29b-41d4-a716-446655440000","content_type":"text","idea":"Create a thread about the top 5 budgeting mistakes millennials make","mode":"mode_1","platforms":["x","pinterest"]}]},"DispatchRunResponse":{"properties":{"run_id":{"type":"string","title":"Run Id"},"job_id":{"type":"string","title":"Job Id"},"mode":{"type":"string","title":"Mode"},"status":{"type":"string","title":"Status","default":"pending"},"message":{"type":"string","title":"Message"}},"type":"object","required":["run_id","job_id","mode","message"],"title":"DispatchRunResponse","description":"Response after enqueuing a pipeline run."},"EventCreate":{"properties":{"name":{"type":"string","maxLength":64,"minLength":1,"title":"Name"},"app_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"App Id"},"props":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Props"}},"type":"object","required":["name"],"title":"EventCreate"},"FeedbackCreate":{"properties":{"text":{"anyOf":[{"type":"string","maxLength":4000,"minLength":1},{"type":"null"}],"title":"Text"},"message":{"anyOf":[{"type":"string","maxLength":4000,"minLength":1},{"type":"null"}],"title":"Message"},"trigger":{"type":"string","pattern":"^(offer|takes|idle|manual)$","title":"Trigger","default":"manual"},"rating":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Rating"},"app_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"App Id"},"page":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Page"},"kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Kind"}},"type":"object","title":"FeedbackCreate"},"FeedbackTriage":{"properties":{"status":{"anyOf":[{"type":"string","pattern":"^(new|planned|implemented|wontdo)$"},{"type":"null"}],"title":"Status"},"note":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Note"},"notified":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Notified"}},"type":"object","title":"FeedbackTriage"},"GalleryAssetRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"batch_id":{"type":"string","format":"uuid","title":"Batch Id"},"app_listing_id":{"type":"string","format":"uuid","title":"App Listing Id"},"app_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"App Name"},"batch_kind":{"type":"string","title":"Batch Kind"},"concept_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Concept Id"},"format_key":{"type":"string","title":"Format Key"},"kind":{"type":"string","title":"Kind"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"},"poster_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Poster Url"},"thumb_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Thumb Url"},"width":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Width"},"height":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Height"},"duration_s":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration S"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","batch_id","app_listing_id","batch_kind","format_key","kind","status","created_at"],"title":"GalleryAssetRead","description":"A finished asset enriched with its batch kind + owning app, for the\nper-app and recent-work galleries. ``storage_path`` is carried only so\n``storage.refresh_urls`` can re-sign ``url`` in place — it's never serialized."},"GoLiveRequest":{"properties":{"app_store_url":{"type":"string","title":"App Store Url","description":"App Store URL or bare numeric Apple app id"}},"type":"object","required":["app_store_url"],"title":"GoLiveRequest","description":"Promote a draft (unreleased) app to live by linking its App Store URL.\nIngest then fills in store metadata/reviews while keeping uploaded screenshots."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"KitCreate":{"properties":{"app_store_url":{"type":"string","title":"App Store Url"},"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"}},"type":"object","required":["app_store_url","email"],"title":"KitCreate"},"KitCreateResponse":{"properties":{"kit_id":{"type":"string","format":"uuid","title":"Kit Id"},"public_token":{"type":"string","title":"Public Token"}},"type":"object","required":["kit_id","public_token"],"title":"KitCreateResponse"},"KitStatusResponse":{"properties":{"status":{"type":"string","title":"Status"},"scorecard":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Scorecard"},"assets":{"items":{"$ref":"#/components/schemas/AssetRead"},"type":"array","title":"Assets"},"signup_url":{"type":"string","title":"Signup Url","default":"https://theagentc.io/signup"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["status"],"title":"KitStatusResponse"},"OfferStartRequest":{"properties":{"trigger":{"type":"string","pattern":"^(declined|idle|returning)$","title":"Trigger"}},"type":"object","required":["trigger"],"title":"OfferStartRequest"},"OveragePackPurchaseRequest":{"properties":{"pack":{"type":"string","pattern":"^(small|medium|large)$","title":"Pack","description":"Size of overage pack to purchase","examples":["small"]}},"type":"object","required":["pack"],"title":"OveragePackPurchaseRequest","description":"Request body for POST /v1/credits/purchase.","example":{"pack":"medium"}},"OveragePackPurchaseResponse":{"properties":{"success":{"type":"boolean","title":"Success","description":"Whether purchase was successful","example":true},"new_balance":{"type":"integer","title":"New Balance","description":"Updated credit balance","example":400},"credits_added":{"type":"integer","title":"Credits Added","description":"Credits added by this pack","example":300},"price_cents":{"type":"integer","title":"Price Cents","description":"Price paid in cents","example":6000},"message":{"type":"string","title":"Message","description":"Confirmation message","example":"Successfully purchased 300 credits for $60.00"}},"type":"object","required":["success","new_balance","credits_added","price_cents","message"],"title":"OveragePackPurchaseResponse","description":"Response after purchasing an overage pack.","example":{"credits_added":300,"message":"Successfully purchased 300 credits for $60.00","new_balance":400,"price_cents":6000,"success":true}},"PlatformStatus":{"properties":{"platform":{"type":"string","title":"Platform"},"connected":{"type":"boolean","title":"Connected"},"account_username":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Username"},"adapter_available":{"type":"boolean","title":"Adapter Available"}},"type":"object","required":["platform","connected","adapter_available"],"title":"PlatformStatus","description":"Status of a single platform connection."},"PlatformStatusResponse":{"properties":{"brand_id":{"type":"string","format":"uuid","title":"Brand Id"},"platforms":{"items":{"$ref":"#/components/schemas/PlatformStatus"},"type":"array","title":"Platforms"}},"type":"object","required":["brand_id","platforms"],"title":"PlatformStatusResponse","description":"All platform statuses for a brand."},"ProgressResponse":{"properties":{"run_id":{"type":"string","format":"uuid","title":"Run Id"},"mode":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mode"},"total_steps":{"type":"integer","title":"Total Steps"},"completed":{"type":"integer","title":"Completed"},"failed":{"type":"integer","title":"Failed"},"skipped":{"type":"integer","title":"Skipped"},"running":{"type":"integer","title":"Running"},"pending":{"type":"integer","title":"Pending"},"percent_complete":{"type":"integer","title":"Percent Complete"},"steps":{"type":"object","title":"Steps"}},"type":"object","required":["run_id","mode","total_steps","completed","failed","skipped","running","pending","percent_complete","steps"],"title":"ProgressResponse"},"PublishResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"platform":{"type":"string","title":"Platform"},"platform_post_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Post Id"},"platform_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform Url"},"status":{"type":"string","title":"Status"},"error_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Message"}},"type":"object","required":["success","platform","status"],"title":"PublishResponse","description":"Result of publishing content to a platform."},"RetryResponse":{"properties":{"run_id":{"type":"string","format":"uuid","title":"Run Id"},"job_id":{"type":"string","format":"uuid","title":"Job Id"},"message":{"type":"string","title":"Message"},"remaining_steps":{"items":{"type":"string"},"type":"array","title":"Remaining Steps"}},"type":"object","required":["run_id","job_id","message","remaining_steps"],"title":"RetryResponse"},"ReviewSummary":{"properties":{"count":{"type":"integer","title":"Count","default":0},"avg_rating":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Rating"},"mined_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mined At"}},"type":"object","title":"ReviewSummary"},"RunCreateInput":{"properties":{"brand_id":{"type":"string","format":"uuid","title":"Brand Id"},"mode":{"type":"integer","maximum":3.0,"minimum":1.0,"title":"Mode","description":"Content mode: 1, 2, or 3"},"idea":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idea"},"video_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Url"},"strategy":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Strategy"},"platforms":{"items":{"type":"string"},"type":"array","title":"Platforms"},"formats":{"items":{"type":"string"},"type":"array","title":"Formats"}},"type":"object","required":["brand_id","mode"],"title":"RunCreateInput","description":"Payload for POST /v1/runs — mirrors `RunCreateInput` in src/lib/api.ts.\n\nKept intentionally loose at the Pydantic layer (strings + lists) so\nvalidation errors surface through `validate_run_request` with the same\nfield names the frontend form uses. That way the UI can highlight the\nright field without a translation table."},"RunDetail":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"brand_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Brand Id"},"campaign_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Campaign Id"},"mode":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mode"},"status":{"type":"string","title":"Status"},"credits_used":{"type":"integer","title":"Credits Used","default":0},"created_at":{"type":"string","title":"Created At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"error":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Error"},"steps_completed":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Steps Completed"},"context":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Context"},"progress":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Progress"}},"type":"object","required":["id","status","created_at"],"title":"RunDetail"},"RunListItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"brand_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Brand Id"},"campaign_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Campaign Id"},"mode":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mode"},"status":{"type":"string","title":"Status"},"credits_used":{"type":"integer","title":"Credits Used","default":0},"created_at":{"type":"string","title":"Created At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"error":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Error"}},"type":"object","required":["id","status","created_at"],"title":"RunListItem"},"RunListResponse":{"properties":{"runs":{"items":{"$ref":"#/components/schemas/RunListItem"},"type":"array","title":"Runs"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"}},"type":"object","required":["runs","total","limit","offset"],"title":"RunListResponse"},"SlideMeta":{"properties":{"slide":{"type":"integer","maximum":5.0,"minimum":0.0,"title":"Slide"},"screen_rect":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Screen Rect"},"regions":{"items":{"$ref":"#/components/schemas/SlideRegionMeta"},"type":"array","title":"Regions"}},"type":"object","required":["slide"],"title":"SlideMeta","description":"Per-slide geometry the Studio region editor needs: where the device's\nscreen area landed in pixels (so it can convert a drag back to a\nscreenshot fraction) and every region the compositor actually drew for\nthat slide. `screen_rect` is null when the slide has no device/screenshot\nat all (nothing to anchor an edit to).\n\nCOORDINATE SPACE — this is request-shape-dependent, read carefully:\n  - Full-strip response (request.slide is null): `rect`/`screen_rect` are\n    STRIP-PIXEL — absolute pixel coords in the full N*slide_w-wide strip\n    image, i.e. slide i's own content starts at x=i*slide_w.\n  - Single-slide response (request.slide is set): `rect`/`screen_rect`\n    are IMAGE-LOCAL — re-based so x=0 is the left edge of the RETURNED\n    image (which is just that one slide, slide_w wide), by subtracting\n    slide*slide_w from every x coordinate. y is unaffected (slides don't\n    stack vertically). This keeps the contract \"rect is always relative\n    to the image actually shipped in `strip`\" true in both modes without\n    the frontend needing to know which mode produced a given response.\nIn both modes the linear mapping contract is unchanged: screenshot_frac\n= (rect - screen_rect.origin) / screen_rect.size."},"SlideRegionMeta":{"properties":{"kind":{"type":"string","title":"Kind"},"idx":{"type":"integer","title":"Idx"},"rect":{"items":{"type":"number"},"type":"array","title":"Rect"},"editable":{"type":"boolean","title":"Editable","default":true}},"type":"object","required":["kind","idx","rect"],"title":"SlideRegionMeta","description":"One editable region's placement inside the preview strip, in STRIP-\nPIXEL coordinates (not fractions) — the Studio region editor draws its\ndrag handles directly at these pixel rects.\n\n`editable=False` for any region on a TILTED slide (see the v1 caveat on\nSlideRegionRect above) — the frontend renders these with no drag handles\nand a small \"Auto-placed (tilted slide)\" note instead."},"SlideRegionRect":{"properties":{"x0":{"type":"number","maximum":1.0,"minimum":0.0,"title":"X0"},"y0":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Y0"},"x1":{"type":"number","maximum":1.0,"minimum":0.0,"title":"X1"},"y1":{"type":"number","maximum":1.0,"minimum":0.0,"title":"Y1"}},"type":"object","required":["x0","y0","x1","y1"],"title":"SlideRegionRect","description":"An explicit rect override, floats 0-1 in SCREENSHOT fractions (the\nRAW screenshot's own width/height — the same coordinate space\nscreenshot_regions.RegionHit.bbox uses). x0<x1, y0<y1 required; a\ndegenerate box (too thin/short to be a legible region) is rejected\nrather than silently clamped.\n\nv1 non-editable-on-tilted-slides caveat: for a TILTED slide (the\nclassic/momentum 45°-bridge hero, or zoom's rotated bookend devices at\nslides 0/5), the render pipeline's recorded `screen_rect` is only the\npost-rotation `expand=True` device bbox — an axis-aligned box 1.65-2.25x\nlarger than the phone's actual visible screen, with no inverse-rotation\nmath to map a Studio drag back to a true screenshot fraction. Posting a\n`region`/`chip_regions` override for a slide that turns out to be tilted\nis still accepted (the backend never 4xx's on it), but the render pass\nreports every region on that slide as `editable: false` in `slides_meta`\n(see SlideMeta/SlideRegionMeta below) so the Studio region editor never\noffers drag handles there, instead of silently round-tripping a user's\nbox to the wrong place. This may be revisited with real rotation-aware\nmapping in a later version."},"SteerUpdate":{"properties":{"steer":{"type":"string","maxLength":2000,"title":"Steer"}},"type":"object","required":["steer"],"title":"SteerUpdate"},"StrategyRequest":{"properties":{"brand_id":{"type":"string","title":"Brand Id","description":"Brand UUID for strategy analysis"},"topic":{"type":"string","maxLength":5000,"minLength":10,"title":"Topic","description":"Strategy topic or question. Be specific for best results."},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id","description":"Existing strategy session UUID to continue (max 6 turns)."}},"type":"object","required":["brand_id","topic"],"title":"StrategyRequest","description":"Request for an Opus-powered strategy session.","examples":[{"brand_id":"550e8400-e29b-41d4-a716-446655440000","topic":"My engagement on X dropped 30% this month. I want to understand why and develop a recovery strategy."}]},"StudioAccessResponse":{"properties":{"studio":{"type":"boolean","title":"Studio"},"unlocked":{"type":"boolean","title":"Unlocked"},"free_unlocks":{"type":"integer","title":"Free Unlocks"}},"type":"object","required":["studio","unlocked","free_unlocks"],"title":"StudioAccessResponse"},"StudioChargeExportRequest":{"properties":{"slots":{"type":"integer","maximum":12.0,"minimum":1.0,"title":"Slots"},"set_key":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Set Key"}},"type":"object","required":["slots"],"title":"StudioChargeExportRequest","description":"POST /v1/apps/{listing_id}/studio/charge-export — the export gate,\ncalled right before the client renders the clean PNGs. Pay-per-set model\n(2026-10-03): allowed when the workspace is on Studio or the set\n(set_key) is unlocked; otherwise 402 {needs: 'unlock'}. No credits."},"StudioChargeExportResponse":{"properties":{"charged":{"type":"integer","title":"Charged"},"new_balance":{"type":"integer","title":"New Balance"}},"type":"object","required":["charged","new_balance"],"title":"StudioChargeExportResponse"},"StudioDirectHero":{"properties":{"type":{"type":"string","title":"Type"},"pills":{"items":{"type":"string"},"type":"array","title":"Pills","default":[]},"scene":{"type":"string","title":"Scene","default":""},"mascot":{"anyOf":[{"items":{"type":"number"},"type":"array"},{"type":"null"}],"title":"Mascot"}},"type":"object","required":["type"],"title":"StudioDirectHero"},"StudioDirectPalette":{"properties":{"bg":{"type":"string","title":"Bg"},"surface":{"type":"string","title":"Surface"},"ink":{"type":"string","title":"Ink"},"accent":{"type":"string","title":"Accent"},"accent2":{"type":"string","title":"Accent2"},"highlight":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Highlight"}},"type":"object","required":["bg","surface","ink","accent","accent2"],"title":"StudioDirectPalette"},"StudioDirectRequest":{"properties":{"screens":{"items":{"type":"string"},"type":"array","maxItems":10,"minItems":1,"title":"Screens"},"focus":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Focus"},"avoid":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":12},{"type":"null"}],"title":"Avoid"},"hero":{"anyOf":[{"type":"string","enum":["hand","icon","lifestyle","phone"]},{"type":"null"}],"title":"Hero"}},"type":"object","required":["screens"],"title":"StudioDirectRequest","description":"POST /v1/apps/{listing_id}/studio/direct — Auto-Direct. `screens` are\nthe Studio's screen-asset URLs in library order (the plan's slide.screen\nindexes into this list). Only this listing's own uploaded screenshots are\naccepted; anything else is ignored server-side."},"StudioDirectResponse":{"properties":{"project_name":{"type":"string","title":"Project Name"},"font":{"type":"string","title":"Font"},"palette":{"$ref":"#/components/schemas/StudioDirectPalette"},"slides":{"items":{"$ref":"#/components/schemas/StudioDirectSlide"},"type":"array","title":"Slides"},"chips":{"items":{"type":"string"},"type":"array","title":"Chips"},"rating":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Rating"},"hero":{"$ref":"#/components/schemas/StudioDirectHero"},"accent_style":{"type":"string","title":"Accent Style","default":"color"},"header":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Header"}},"type":"object","required":["project_name","font","palette","slides","chips","hero"],"title":"StudioDirectResponse"},"StudioDirectSlide":{"properties":{"screen":{"type":"integer","title":"Screen"},"headline":{"type":"string","title":"Headline"},"subline":{"type":"string","title":"Subline"},"popouts":{"items":{"items":{"type":"number"},"type":"array"},"type":"array","title":"Popouts"},"layout":{"type":"string","title":"Layout","default":"standard"},"stickers":{"items":{"$ref":"#/components/schemas/StudioDirectSticker"},"type":"array","title":"Stickers","default":[]}},"type":"object","required":["screen","headline","subline","popouts"],"title":"StudioDirectSlide"},"StudioDirectSticker":{"properties":{"text":{"type":"string","title":"Text"},"y":{"type":"number","title":"Y"}},"type":"object","required":["text","y"],"title":"StudioDirectSticker"},"StudioPhotoRequest":{"properties":{"scene":{"type":"string","maxLength":400,"minLength":3,"title":"Scene"},"mascot_screen":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mascot Screen"},"mascot_box":{"anyOf":[{"items":{"type":"number"},"type":"array","maxItems":4,"minItems":4},{"type":"null"}],"title":"Mascot Box"},"wide":{"type":"boolean","title":"Wide","default":false}},"type":"object","required":["scene"],"title":"StudioPhotoRequest","description":"POST /v1/apps/{listing_id}/studio/photo — Auto-Direct lifestyle hero.\n`mascot` optionally names one of the listing's own uploaded screenshots +\na box to crop a character from, so it can appear in the photo."},"StudioPhotoResponse":{"properties":{"url":{"type":"string","title":"Url"},"cached":{"type":"boolean","title":"Cached"}},"type":"object","required":["url","cached"],"title":"StudioPhotoResponse"},"StudioResignRequest":{"properties":{"urls":{"items":{"type":"string"},"type":"array","maxItems":80,"minItems":1,"title":"Urls"}},"type":"object","required":["urls"],"title":"StudioResignRequest","description":"POST /v1/apps/{listing_id}/studio/resign — swap expired studio asset\nURLs for freshly-signed ones. GCS v4 signed URLs are capped at 7 days, but\nthe Studio persists asset/background URLs in localStorage indefinitely, so\nAI scenes + sprites rot after a week with no recovery path."},"StudioSceneRequest":{"properties":{"prompt":{"type":"string","maxLength":600,"minLength":1,"title":"Prompt"},"width":{"type":"integer","maximum":4096.0,"minimum":64.0,"title":"Width"},"height":{"type":"integer","maximum":4096.0,"minimum":64.0,"title":"Height"},"theme":{"anyOf":[{"$ref":"#/components/schemas/StudioThemeHex"},{"type":"null"}]}},"type":"object","required":["prompt","width","height"],"title":"StudioSceneRequest","description":"POST /v1/apps/{listing_id}/studio/scene — SPEC §3.4.4's 'Paint scene'\nhook (window.ASCStudio.registerSceneGenerator). Generates ONE low-res\npreview-quality background at up to studio_gen.SCENE_MAX_W, cached by\ncontent hash under studio-scenes/{workspace_id}/. Not credit-gated —\ncomposing is free; only export charges credits (see StudioChargeExportRequest)."},"StudioSceneResponse":{"properties":{"url":{"type":"string","title":"Url"},"cached":{"type":"boolean","title":"Cached"}},"type":"object","required":["url","cached"],"title":"StudioSceneResponse"},"StudioSpriteRequest":{"properties":{"prompt":{"type":"string","maxLength":400,"minLength":1,"title":"Prompt"}},"type":"object","required":["prompt"],"title":"StudioSpriteRequest","description":"POST /v1/apps/{listing_id}/studio/sprite — SPEC §3.5's 'Generate\nsprite' hook (window.ASCStudio.registerSpriteGenerator). Not credit-gated."},"StudioSpriteResponse":{"properties":{"url":{"type":"string","title":"Url"},"cached":{"type":"boolean","title":"Cached"}},"type":"object","required":["url","cached"],"title":"StudioSpriteResponse"},"StudioThemeHex":{"properties":{"bg":{"anyOf":[{"type":"string","maxLength":9},{"type":"null"}],"title":"Bg"},"accent":{"anyOf":[{"type":"string","maxLength":9},{"type":"null"}],"title":"Accent"},"accent2":{"anyOf":[{"type":"string","maxLength":9},{"type":"null"}],"title":"Accent2"}},"type":"object","title":"StudioThemeHex","description":"A subset of the Studio's Theme palette (src/lib/studio/types.ts) — just\nthe hexes worth blending into an AI scene prompt so a generated\nbackground harmonizes with the active palette (SPEC §3.4.4)."},"StudioUnlockRequest":{"properties":{"set_key":{"type":"string","maxLength":64,"minLength":8,"title":"Set Key"},"offer":{"type":"boolean","title":"Offer","default":false}},"type":"object","required":["set_key"],"title":"StudioUnlockRequest","description":"POST /v1/apps/{listing_id}/studio/unlock — unlock one set for clean\ndownload: free if on Studio or a free unlock remains, else a Stripe\nCheckout ($9.99) URL."},"StudioUnlockResponse":{"properties":{"unlocked":{"type":"boolean","title":"Unlocked"},"used_free":{"type":"boolean","title":"Used Free","default":false},"checkout_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Checkout Url"}},"type":"object","required":["unlocked"],"title":"StudioUnlockResponse"},"TopUpRequest":{"properties":{"to":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"To","description":"Target credit balance","default":100}},"type":"object","title":"TopUpRequest"},"UsageSummary":{"properties":{"total_spent":{"type":"integer","title":"Total Spent","description":"Total credits spent (absolute value)","example":50},"total_earned":{"type":"integer","title":"Total Earned","description":"Total credits earned (e.g., from resets)","example":200},"breakdown_by_reason":{"additionalProperties":{"type":"integer"},"type":"object","title":"Breakdown By Reason","description":"Credit changes grouped by reason","example":{"mode_1_text":-1,"mode_1_video":-18,"monthly_reset":200}},"period_start":{"type":"string","format":"date-time","title":"Period Start","description":"Start of billing period","example":"2026-03-07T08:30:00Z"},"period_end":{"type":"string","format":"date-time","title":"Period End","description":"End of billing period (next reset)","example":"2026-04-07T08:30:00Z"}},"type":"object","required":["total_spent","total_earned","breakdown_by_reason","period_start","period_end"],"title":"UsageSummary","description":"Aggregate credit usage for current billing period.","example":{"breakdown_by_reason":{"mode_1_text":-1,"mode_1_video":-18,"monthly_reset":200},"period_end":"2026-04-07T08:30:00Z","period_start":"2026-03-07T08:30:00Z","total_earned":200,"total_spent":50}},"UserCreate":{"properties":{"email":{"type":"string","title":"Email"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"workspace_name":{"type":"string","title":"Workspace Name"}},"type":"object","required":["email","workspace_name"],"title":"UserCreate","description":"Used during onboarding — creates user + workspace."},"UserRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"uid":{"type":"string","title":"Uid"},"email":{"type":"string","title":"Email"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Avatar Url"},"workspace_id":{"type":"string","format":"uuid","title":"Workspace Id"},"role":{"type":"string","title":"Role"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","uid","email","display_name","avatar_url","workspace_id","role","created_at"],"title":"UserRead"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VideoCreate":{"properties":{"length_s":{"type":"integer","enum":[7,15,25],"title":"Length S","default":15},"premium":{"type":"boolean","title":"Premium","default":false}},"type":"object","title":"VideoCreate"},"WorkspaceRead":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"plan":{"type":"string","title":"Plan"},"status":{"type":"string","title":"Status"},"credits_remaining":{"type":"integer","title":"Credits Remaining"},"credits_total":{"type":"integer","title":"Credits Total"},"credits_reset_at":{"type":"string","format":"date-time","title":"Credits Reset At"},"video_count_this_month":{"type":"integer","title":"Video Count This Month"},"video_cap":{"type":"integer","title":"Video Cap"},"autonomy_level":{"type":"string","title":"Autonomy Level"},"onboarded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Onboarded At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","name","plan","status","credits_remaining","credits_total","credits_reset_at","video_count_this_month","video_cap","autonomy_level","created_at"],"title":"WorkspaceRead"},"WorkspaceUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"autonomy_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Autonomy Level"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"mark_onboarded":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Mark Onboarded"}},"type":"object","title":"WorkspaceUpdate"},"app__schemas__brand__BrandUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"niche":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Niche"},"soul_config":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Soul Config"},"brand_kit":{"anyOf":[{"type":"object"},{"type":"null"}],"title":"Brand Kit"},"content_pillars":{"anyOf":[{"items":{"type":"object"},"type":"array"},{"type":"null"}],"title":"Content Pillars"}},"type":"object","title":"BrandUpdate"},"app__schemas__creative__BrandUpdate":{"properties":{"accent":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Accent"},"bg":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Bg"},"card":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Card"},"ink":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Ink"},"warm":{"anyOf":[{"items":{"type":"integer"},"type":"array"},{"type":"null"}],"title":"Warm"},"style":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Style"},"brand_line":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Brand Line"}},"type":"object","title":"BrandUpdate","description":"Manual brand-kit overrides. Any field set here is pinned so a later\nbrand refresh won't overwrite it. RGB fields are [r, g, b] 0-255."}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}