{"openapi":"3.1.0","info":{"title":"Send API","version":"1.0.0","description":"Promotional email for AI agents. Pay per send; the price per email depends on the workspace currency (₩2 or $0.002), unlimited contacts.\n\nAuth: `Authorization: Bearer sd_live_…` (create keys in Settings → API keys). Errors: `{ error, code }` — messages follow the request locale (ko/en). Money: every `*_krw` field is an integer in the workspace currency's minor unit — won for KRW, micro-dollars (1 USD = 1,000,000) for USD; read `workspace.currency` to format. Emails lowercase.\n\nThe loop: `POST /api/v1/ai/campaign { brief, list_names }` → status `awaiting_approval` (approve mode) → `POST /api/v1/campaigns/{id}/approve` (or the emailed /a/{token} page) → send → `GET /{id}/report` → learning memo (`GET /api/v1/learning`) improves the next brief. Autopilot mode manual|approve|auto via `/api/v1/autopilot/settings`; recurring plans via `/api/v1/autopilot/plans`.","contact":{"email":"contact@ai3.kr"}},"servers":[{"url":"https://send.ad"}],"tags":[{"name":"Account"},{"name":"Team"},{"name":"Billing"},{"name":"Audience"},{"name":"Forms"},{"name":"Templates"},{"name":"AI"},{"name":"Campaigns"},{"name":"Send"},{"name":"Domains"},{"name":"Automations"},{"name":"Autopilot"},{"name":"Learning"},{"name":"Reports"},{"name":"Webhooks"}],"security":[{"apiKey":[]}],"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"sd_live_… API key"}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable message in the request locale (ko or en — cookie send_locale / Accept-Language)"},"code":{"type":"string","description":"Machine code, e.g. insufficient_balance"}},"required":["error"]},"Page":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}},"Workspace":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"company_name":{"type":"string"},"address":{"type":"string"},"phone":{"type":"string"},"contact_email":{"type":"string"},"website":{"type":"string"},"logo_url":{"type":"string"},"brand_color":{"type":"string","description":"#rrggbb"},"brand_profile":{"$ref":"#/components/schemas/BrandProfile"},"default_from_name":{"type":"string"},"default_from_email":{"type":"string"},"default_reply_to":{"type":"string"},"ad_prefix_default":{"type":"boolean","description":"Prefix subjects with (광고) by default"},"night_consent":{"type":"boolean","description":"Recipients gave separate consent for 21:00–08:00 KST delivery"},"send_rate_per_min":{"type":"integer"},"balance_krw":{"type":"number","description":"Balance in the workspace currency's minor unit (see currency)"},"unit_price_krw":{"type":"number","description":"Price per email in the minor unit"},"locale":{"type":"string","enum":["ko","en"],"description":"Language for AI copy, mail footers and ledger memos"},"region":{"type":"string","enum":["kr","global"],"description":"kr: Korean ad-mail rules (광고 prefix, night consent) · global: CAN-SPAM"},"currency":{"type":"string","enum":["KRW","USD"],"description":"KRW: integers are won · USD: integers are micro-dollars (1 USD = 1,000,000)"},"timezone":{"type":"string","description":"IANA timezone (e.g. America/New_York) — dates, autopilot run times and daily report boundaries follow it"},"provider":{"type":"string","enum":["platform","sendgrid","smtp","ses","resend"]},"sender_profile_complete":{"type":"boolean"}}},"BrandProfile":{"type":"object","properties":{"tone":{"type":"string","description":"Voice and tone guidance for AI"},"audience":{"type":"string"},"signature":{"type":"string"},"do_not_say":{"type":"string"},"products":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"url":{"type":"string"},"price":{"type":"string"}}}},"links":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"url":{"type":"string"}}}}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"prefix":{"type":"string","description":"First 12 chars, e.g. sd_live_abcd"},"last_used_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"revoked_at":{"type":"string","format":"date-time"}}},"ApiKeyCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string","description":"Full key — shown only once"},"prefix":{"type":"string"}}},"Member":{"type":"object","properties":{"user_id":{"type":"string","format":"uuid"},"email":{"type":"string"},"display_name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"]},"status":{"type":"string","enum":["active","suspended"]},"last_seen_at":{"type":"string","format":"date-time"},"joined_at":{"type":"string","format":"date-time"}}},"Invite":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"role":{"type":"string","enum":["admin","member"]},"url":{"type":"string"},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"Billing":{"type":"object","properties":{"currency":{"type":"string","enum":["KRW","USD"]},"provider":{"type":"string","enum":["toss","stripe"]},"unit_price":{"type":"number","description":"Per email, in storage units (KRW won / USD micro-dollars)"},"min_topup":{"type":"number"},"packs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"amount":{"type":"number"},"label":{"type":"string"}}}},"balance_krw":{"type":"number","description":"Balance in storage units of `currency` (column name is historical)"},"unit_price_krw":{"type":"number"},"sends_left":{"type":"integer"},"has_card":{"type":"boolean"},"card_label":{"type":"string"},"auto_recharge":{"type":"object","properties":{"enabled":{"type":"boolean"},"threshold_krw":{"type":"number"},"amount_krw":{"type":"number"}}},"pricing":{"type":"object","properties":{"unit_price_krw":{"type":"number"},"signup_bonus_krw":{"type":"number"},"min_topup_krw":{"type":"number"},"vat_rate":{"type":"number"},"packs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"amountKrw":{"type":"number"},"label":{"type":"string"}}}}}},"month":{"type":"object","properties":{"sends":{"type":"integer"},"cost_krw":{"type":"number"}}},"ledger":{"type":"array","items":{"$ref":"#/components/schemas/LedgerEntry"}},"payments":{"type":"array","items":{"$ref":"#/components/schemas/Payment"}}}},"LedgerEntry":{"type":"object","properties":{"id":{"type":"integer"},"delta_krw":{"type":"number"},"kind":{"type":"string","enum":["signup_bonus","topup","auto_topup","reserve","charge","refund","adjust"]},"memo":{"type":"string"},"ref_type":{"type":"string"},"ref_id":{"type":"string"},"balance_after":{"type":"number"},"created_at":{"type":"string","format":"date-time"}}},"Payment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["topup","auto_topup"]},"order_id":{"type":"string"},"amount_krw":{"type":"number","description":"Charged to card (VAT included)"},"credit_krw":{"type":"number","description":"Added to balance"},"status":{"type":"string","enum":["pending","paid","failed"]},"receipt_url":{"type":"string"},"card_label":{"type":"string"},"error":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"paid_at":{"type":"string","format":"date-time"}}},"Usage":{"type":"object","properties":{"month":{"type":"string","description":"YYYY-MM"},"days":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"sends":{"type":"integer"},"cost_krw":{"type":"number"}}}},"total_sends":{"type":"integer"},"total_cost_krw":{"type":"number"}}},"Contact":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"attrs":{"type":"object","properties":{},"description":"Free-form attributes, usable as {{attr.key}} merge tags"},"status":{"type":"string","enum":["subscribed","unsubscribed","bounced","complained","pending"]},"source":{"type":"string"},"list_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"tags":{"type":"array","items":{"type":"string"}},"subscribed_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"ContactInput":{"type":"object","properties":{"email":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"attrs":{"type":"object","properties":{}},"list_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"tags":{"type":"array","items":{"type":"string","description":"Tag names; created if missing"}}},"required":["email"]},"List":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string"},"double_opt_in":{"type":"boolean"},"contacts_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}},"Tag":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"contacts_count":{"type":"integer"}}},"Segment":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"rules":{"$ref":"#/components/schemas/SegmentRules"},"created_at":{"type":"string","format":"date-time"}}},"SegmentRules":{"type":"object","properties":{"match":{"type":"string","enum":["all","any"]},"conditions":{"type":"array","items":{"type":"object","properties":{"field":{"type":"string","description":"list | tag | status | attr.<key> | email | first_name"},"op":{"type":"string","enum":["in","not_in","eq","neq","contains","exists"]},"value":{}}}}}},"Suppression":{"type":"object","properties":{"id":{"type":"integer"},"email":{"type":"string"},"reason":{"type":"string","enum":["unsubscribe","bounce","complaint","manual","import"]},"created_at":{"type":"string","format":"date-time"}}},"Form":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"slug":{"type":"string"},"name":{"type":"string"},"list_id":{"type":"string","format":"uuid"},"fields":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"label":{"type":"string"},"type":{"type":"string"},"required":{"type":"boolean"}}}},"title":{"type":"string"},"description":{"type":"string"},"button_text":{"type":"string"},"success_message":{"type":"string"},"redirect_url":{"type":"string"},"double_opt_in":{"type":"boolean"},"submissions":{"type":"integer"},"hosted_url":{"type":"string"},"embed_code":{"type":"string"}}},"Import":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"total":{"type":"integer"},"imported":{"type":"integer"},"updated":{"type":"integer"},"skipped":{"type":"integer"},"suppressed":{"type":"integer"},"status":{"type":"string","enum":["running","done","failed"]},"errors":{"type":"array","items":{"type":"string"}}}},"Design":{"type":"object","properties":{"version":{"type":"integer","const":1},"settings":{"type":"object","properties":{"width":{"type":"integer","description":"480–720, default 600"},"bg":{"type":"string"},"contentBg":{"type":"string"},"fontFamily":{"type":"string"},"textColor":{"type":"string"},"mutedColor":{"type":"string"},"linkColor":{"type":"string"},"brandColor":{"type":"string"},"radius":{"type":"integer"},"padding":{"type":"integer"}}},"blocks":{"type":"array","items":{"$ref":"#/components/schemas/Block"}}},"required":["blocks"],"description":"Email design JSON. Rendered server-side to table-based HTML. Merge tags {{first_name|고객}} allowed in text."},"Block":{"oneOf":[{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"header"},"logoUrl":{"type":"string"},"logoWidth":{"type":"integer"},"text":{"type":"string"},"href":{"type":"string"},"align":{"type":"string","enum":["left","center","right"]},"bg":{"type":"string"}},"required":["id","type"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"heading"},"text":{"type":"string"},"level":{"type":"string","enum":["1","2","3"]},"align":{"type":"string"},"color":{"type":"string"}},"required":["id","type","text"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"text"},"html":{"type":"string","description":"Limited rich HTML: p br b i u a ul ol li span"},"align":{"type":"string"},"fontSize":{"type":"integer"},"color":{"type":"string"}},"required":["id","type","html"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"image"},"src":{"type":"string"},"alt":{"type":"string"},"href":{"type":"string"},"widthPct":{"type":"integer"},"align":{"type":"string"},"radius":{"type":"integer"}},"required":["id","type","src"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"gallery"},"images":{"type":"array","items":{"type":"object","properties":{"src":{"type":"string"},"alt":{"type":"string"},"href":{"type":"string"}},"required":["src"]}},"columns":{"type":"integer","description":"2 or 3"},"gap":{"type":"integer"},"radius":{"type":"integer"}},"required":["id","type","images"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"video"},"url":{"type":"string","description":"video page URL (YouTube etc.) — rendered as thumbnail + button link; email cannot play video"},"thumbnail":{"type":"string","description":"optional; YouTube thumbnails are derived automatically"},"title":{"type":"string"},"buttonText":{"type":"string"},"radius":{"type":"integer"}},"required":["id","type","url"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"button"},"text":{"type":"string"},"href":{"type":"string"},"align":{"type":"string"},"bg":{"type":"string"},"color":{"type":"string"},"radius":{"type":"integer"},"fullWidth":{"type":"boolean"},"size":{"type":"string","enum":["sm","md","lg"]}},"required":["id","type","text","href"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"divider"},"color":{"type":"string"},"thickness":{"type":"integer"},"widthPct":{"type":"integer"}},"required":["id","type"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"spacer"},"height":{"type":"integer"}},"required":["id","type"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"social"},"align":{"type":"string"},"links":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["instagram","facebook","x","youtube","linkedin","kakao","blog","web","threads"]},"href":{"type":"string"}}}}},"required":["id","type"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"footer"},"html":{"type":"string"},"align":{"type":"string"}},"required":["id","type"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"html"},"html":{"type":"string"}},"required":["id","type","html"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"product"},"image":{"type":"string"},"title":{"type":"string"},"price":{"type":"string"},"originalPrice":{"type":"string"},"description":{"type":"string"},"href":{"type":"string"},"buttonText":{"type":"string"},"layout":{"type":"string","enum":["stack","row"]}},"required":["id","type","title"]},{"type":"object","properties":{"id":{"type":"string"},"type":{"const":"columns"},"columns":{"type":"array","items":{"type":"object","properties":{"blocks":{"type":"array","items":{"$ref":"#/components/schemas/Block"}}}}},"gap":{"type":"integer"},"stackOnMobile":{"type":"boolean"}},"required":["id","type","columns"]}]},"Template":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"workspace_id":{"type":"string","format":"uuid","description":"null for platform starters"},"name":{"type":"string"},"category":{"type":"string"},"description":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"},"thumbnail_url":{"type":"string"},"is_starter":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Rendered":{"type":"object","properties":{"html":{"type":"string"},"text":{"type":"string"}}},"Audience":{"type":"object","properties":{"list_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"tag_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"segment_id":{"type":"string","format":"uuid"},"exclude_list_ids":{"type":"array","items":{"type":"string","format":"uuid"}}},"description":"Recipients = subscribed contacts in any list/tag (∩ segment) minus exclude lists minus suppression list"},"Campaign":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"created_via":{"type":"string","enum":["ui","api","cli","ai","autopilot"]},"suggested_send_at":{"type":"string","format":"date-time","description":"AI-recommended send time from learning memo"},"approved_at":{"type":"string","format":"date-time"},"reject_note":{"type":"string"},"autopilot_plan_id":{"type":"string","format":"uuid"},"name":{"type":"string"},"subject":{"type":"string"},"preheader":{"type":"string"},"from_name":{"type":"string"},"from_email":{"type":"string"},"reply_to":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"},"html_override":{"type":"string"},"audience":{"$ref":"#/components/schemas/Audience"},"ad_prefix":{"type":"boolean"},"track_opens":{"type":"boolean"},"track_clicks":{"type":"boolean"},"utm":{"type":"object","properties":{}},"status":{"type":"string","enum":["draft","awaiting_approval","scheduled","queued","sending","paused","sent","canceled","failed"],"description":"awaiting_approval = AI/autopilot draft waiting for one approval (POST /{id}/approve or the emailed /a/{token} page)"},"scheduled_at":{"type":"string","format":"date-time"},"started_at":{"type":"string","format":"date-time"},"finished_at":{"type":"string","format":"date-time"},"recipients_total":{"type":"integer"},"sent_count":{"type":"integer"},"delivered_count":{"type":"integer"},"open_count":{"type":"integer"},"unique_open_count":{"type":"integer"},"click_count":{"type":"integer"},"unique_click_count":{"type":"integer"},"bounce_count":{"type":"integer"},"complaint_count":{"type":"integer"},"unsubscribe_count":{"type":"integer"},"failed_count":{"type":"integer"},"reserved_krw":{"type":"number"},"cost_krw":{"type":"number"},"ai_brief":{"type":"string"},"error":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"CampaignInput":{"type":"object","properties":{"name":{"type":"string"},"subject":{"type":"string"},"preheader":{"type":"string"},"from_name":{"type":"string"},"from_email":{"type":"string"},"reply_to":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"},"html_override":{"type":"string"},"template_id":{"type":"string","format":"uuid","description":"Copy design from a template"},"audience":{"$ref":"#/components/schemas/Audience"},"ad_prefix":{"type":"boolean"},"track_opens":{"type":"boolean"},"track_clicks":{"type":"boolean"},"utm":{"type":"object","properties":{}},"scheduled_at":{"type":"string","format":"date-time"}}},"Estimate":{"type":"object","properties":{"recipients":{"type":"integer"},"cost_krw":{"type":"number"},"balance_krw":{"type":"number"},"ok":{"type":"boolean","description":"balance ≥ cost and sender profile complete"},"reasons":{"type":"array","items":{"type":"string"}}}},"Report":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"},"rates":{"type":"object","properties":{"delivered":{"type":"number"},"open":{"type":"number"},"click":{"type":"number"},"bounce":{"type":"number"},"unsubscribe":{"type":"number"}}},"links":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"clicks":{"type":"integer"},"unique_clicks":{"type":"integer"}}}},"timeline":{"type":"array","items":{"type":"object","properties":{"hour":{"type":"string"},"opens":{"type":"integer"},"clicks":{"type":"integer"}}}}}},"Delivery":{"type":"object","properties":{"id":{"type":"integer"},"token":{"type":"string"},"email":{"type":"string"},"kind":{"type":"string","enum":["campaign","transactional","automation","test","confirm","system"]},"status":{"type":"string","enum":["queued","sending","sent","delivered","deferred","bounced","dropped","failed"]},"subject":{"type":"string"},"cost_krw":{"type":"integer"},"sent_at":{"type":"string","format":"date-time"},"delivered_at":{"type":"string","format":"date-time"},"opened_at":{"type":"string","format":"date-time"},"clicked_at":{"type":"string","format":"date-time"},"error":{"type":"string"}}},"SendInput":{"type":"object","properties":{"to":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"subject":{"type":"string"},"html":{"type":"string"},"text":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"},"from_name":{"type":"string"},"from_email":{"type":"string"},"reply_to":{"type":"string"},"merge":{"type":"object","properties":{},"description":"Merge values for {{tags}}"}},"required":["to","subject"]},"Domain":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"domain":{"type":"string"},"status":{"type":"string","enum":["pending","verified","failed"]},"dns_records":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"host":{"type":"string"},"value":{"type":"string"},"valid":{"type":"boolean"}}}},"verified_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"Automation":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"trigger":{"type":"object","properties":{"type":{"const":"list_subscribe"},"list_id":{"type":"string","format":"uuid"}}},"steps":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"const":"delay"},"hours":{"type":"number"}}},{"type":"object","properties":{"type":{"const":"send"},"subject":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"}}}]}},"status":{"type":"string","enum":["active","paused"]},"runs_total":{"type":"integer"}}},"Event":{"type":"object","properties":{"id":{"type":"integer"},"type":{"type":"string","enum":["sent","delivered","deferred","open","click","bounce","complaint","unsubscribe","dropped","failed"]},"campaign_id":{"type":"string","format":"uuid"},"contact_id":{"type":"string","format":"uuid"},"url":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"AiCampaignInput":{"type":"object","properties":{"brief":{"type":"string","description":"One-line brief: what, for whom, until when, the offer"},"list_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"list_names":{"type":"array","items":{"type":"string","description":"Resolve lists by name (CLI convenience)"}},"tag_ids":{"type":"array","items":{"type":"string","format":"uuid"}},"segment_id":{"type":"string","format":"uuid"},"tone":{"type":"string"},"name":{"type":"string"},"created_via":{"type":"string","enum":["ui","api","cli","ai","autopilot"]},"send":{"type":"boolean","description":"Request immediate send. In approve mode the campaign becomes awaiting_approval instead; in auto mode it sends when guardrails pass"},"scheduled_at":{"type":"string","format":"date-time","description":"Schedule instead of sending now"}},"required":["brief"]},"AiCampaignOutput":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"},"status":{"type":"string","enum":["draft","awaiting_approval","queued","scheduled"]},"mode":{"type":"string","enum":["manual","approve","auto"]},"subjects":{"type":"array","items":{"type":"string"}},"preview_url":{"type":"string"},"approval_url":{"type":"string","description":"One-click approval page /a/{token} (no login)"},"guardrail_reasons":{"type":"array","items":{"type":"string"}},"suggested_send_at":{"type":"string","format":"date-time"},"estimate":{"$ref":"#/components/schemas/Estimate"}}},"Approval":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"subject":{"type":"string"},"created_via":{"type":"string"},"suggested_send_at":{"type":"string","format":"date-time"},"estimate":{"$ref":"#/components/schemas/Estimate"},"approval_url":{"type":"string"},"preview_url":{"type":"string"},"created_at":{"type":"string","format":"date-time"}}},"AutopilotSettings":{"type":"object","properties":{"mode":{"type":"string","enum":["manual","approve","auto"],"description":"manual: AI only drafts · approve: one human approval per campaign (default) · auto: send when guardrails pass, else awaiting_approval"},"guardrails":{"type":"object","properties":{"max_sends_per_day":{"type":"integer"},"quiet_hours":{"type":"array","items":{"type":"integer"},"description":"[startHour, endHour] KST — no auto sends inside"},"min_balance_krw":{"type":"number"},"require_approval_over_recipients":{"type":"integer"}}},"approval_emails":{"type":"array","items":{"type":"string","description":"Who receives the approval mail with the /a/{token} link"}}}},"Cadence":{"type":"object","properties":{"type":{"type":"string","enum":["daily","weekly","biweekly","monthly"]},"dow":{"type":"integer","description":"0–6 for weekly/biweekly"},"dom":{"type":"integer","description":"1–28 for monthly"},"hour":{"type":"integer","description":"0–23 in the workspace timezone"},"minute":{"type":"integer"},"tz":{"type":"string","description":"IANA timezone — set from the workspace; read-only"}},"required":["type","hour"]},"AutopilotPlan":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"cadence":{"$ref":"#/components/schemas/Cadence"},"cadence_label":{"type":"string"},"brief_template":{"type":"string","description":"May use {{date}} {{recent_posts}} {{products}} {{free_text}}"},"sources":{"type":"object","properties":{"rss_url":{"type":"string"},"free_text":{"type":"string"}}},"audience":{"$ref":"#/components/schemas/Audience"},"tone":{"type":"string"},"status":{"type":"string","enum":["active","paused"]},"next_run_at":{"type":"string","format":"date-time"},"last_run_at":{"type":"string","format":"date-time"},"last_campaign_id":{"type":"string","format":"uuid"},"last_error":{"type":"string"},"runs":{"type":"integer"}}},"Learning":{"type":"object","properties":{"memo":{"type":"string","description":"AI-written memo of what worked; injected into the next /ai/campaign prompt"},"bullets":{"type":"array","items":{"type":"string"}},"best_hours":{"type":"array","items":{"type":"integer","description":"hours 0–23 in the workspace timezone"}},"stats":{"type":"object","properties":{}},"version":{"type":"integer"},"updated_at":{"type":"string","format":"date-time"},"recent":{"type":"array","items":{"type":"object","properties":{"campaign_id":{"type":"string","format":"uuid"},"name":{"type":"string"},"insight":{"type":"string"}}}}}},"NextSuggestions":{"type":"object","properties":{"subjects":{"type":"array","items":{"type":"string"}},"send_hour":{"type":"integer"},"send_dow":{"type":"integer"},"cta":{"type":"string"},"rationale":{"type":"array","items":{"type":"string"}},"suggested_send_at":{"type":"string","format":"date-time"},"send_when_label":{"type":"string"}}}}},"paths":{"/api/v1/me":{"get":{"summary":"Who am I (API key → workspace)","tags":["Account"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"via":{"type":"string","enum":["session","apikey"]},"role":{"type":"string"},"workspace":{"$ref":"#/components/schemas/Workspace"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspace":{"get":{"summary":"Get workspace (sender profile, brand profile, defaults)","tags":["Account"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workspace":{"$ref":"#/components/schemas/Workspace"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update workspace (admin)","tags":["Account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"workspace":{"$ref":"#/components/schemas/Workspace"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/workspace/provider":{"put":{"summary":"Set sending provider (BYO SendGrid/SMTP/SES) (admin)","tags":["Account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","enum":["platform","sendgrid","smtp","ses"]},"config":{"type":"object","properties":{}}},"required":["provider"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/apikeys":{"get":{"summary":"List API keys (admin)","tags":["Account"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create API key (full key returned once) (admin)","tags":["Account"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyCreated"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/apikeys/{id}":{"delete":{"summary":"Revoke API key (admin)","tags":["Account"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team":{"get":{"summary":"Members and pending invites","tags":["Team"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string"},"members":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"invites":{"type":"array","items":{"$ref":"#/components/schemas/Invite"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/invites":{"post":{"summary":"Invite by email(s) (admin)","tags":["Team"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"emails":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"role":{"type":"string","enum":["admin","member"]}},"required":["emails"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"created":{"type":"array","items":{"$ref":"#/components/schemas/Invite"}},"skipped":{"type":"array","items":{"type":"string"}},"mailed":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/invites/{id}":{"delete":{"summary":"Cancel invite (admin)","tags":["Team"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/invites/{id}/resend":{"post":{"summary":"Resend invite mail (admin)","tags":["Team"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"url":{"type":"string"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/members/{userId}":{"put":{"summary":"Change role or status (admin)","tags":["Team"],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["admin","member"]},"status":{"type":"string","enum":["active","suspended"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Remove member (admin)","tags":["Team"],"parameters":[{"name":"userId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/transfer":{"post":{"summary":"Transfer ownership (owner only) (admin)","tags":["Team"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string","format":"uuid"}},"required":["user_id"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/audit":{"get":{"summary":"Audit log (admin)","tags":["Team"],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"default 50, max 500"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"action":{"type":"string"},"target":{"type":"string"},"meta":{"type":"object","properties":{}},"created_at":{"type":"string","format":"date-time"},"user_email":{"type":"string"}}}},"labels":{"type":"object","properties":{}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/join/{token}":{"get":{"summary":"Invite info","tags":["Team"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"invite":{"type":"object","properties":{"email":{"type":"string"},"role":{"type":"string"},"workspace_name":{"type":"string"},"expired":{"type":"boolean"},"accepted":{"type":"boolean"}}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[]},"post":{"summary":"Accept invite (session)","tags":["Team"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"workspace_id":{"type":"string","format":"uuid"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing":{"get":{"summary":"Balance, unit price, card, ledger, payments","tags":["Billing"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing/card":{"post":{"summary":"Register card (KRW only · Toss billing authKey → billing key). USD cards are saved by the first Stripe Checkout (admin)","tags":["Billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"authKey":{"type":"string"},"customerKey":{"type":"string"}},"required":["authKey"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"card_label":{"type":"string"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Remove the saved card (Toss key or Stripe payment method) and turn auto-recharge off (admin)","tags":["Billing"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing/topup":{"post":{"summary":"Top up balance — KRW: charge the registered Toss card now (VAT added); USD: returns a Stripe Checkout URL (admin)","tags":["Billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"pack_id":{"type":"string","description":"Pack id from GET /api/v1/billing packs (t10k… or u10…)"},"amount":{"type":"number","description":"Custom amount in storage units (KRW ≥ 10,000 multiple of 1,000 · USD ≥ 10,000,000 micro = $10)"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"amount_krw":{"type":"number"},"charged_krw":{"type":"number"},"balance_krw":{"type":"number"},"receipt_url":{"type":"string"},"checkout_url":{"type":"string","description":"USD only — redirect the user here"},"session_id":{"type":"string"},"payment_id":{"type":"string","format":"uuid"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing/stripe/confirm":{"post":{"summary":"USD: settle a Checkout session if the webhook has not arrived yet (admin)","tags":["Billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"session_id":{"type":"string"}},"required":["session_id"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string"},"balance":{"type":"number"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing/auto-recharge":{"put":{"summary":"Auto-recharge settings (admin)","tags":["Billing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"thresholdKrw":{"type":"number"},"amountKrw":{"type":"number"}},"required":["enabled"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/billing/usage":{"get":{"summary":"Sends and cost per day for a month","tags":["Billing"],"parameters":[{"name":"month","in":"query","required":false,"schema":{"type":"string"},"description":"YYYY-MM (default current)"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contacts":{"get":{"summary":"List contacts","tags":["Audience"],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"list_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"tag_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"default 50, max 500"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create or update a contact (upsert by email)","tags":["Audience"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"$ref":"#/components/schemas/Contact"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contacts/{id}":{"get":{"summary":"Get contact","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"$ref":"#/components/schemas/Contact"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update contact","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"contact":{"$ref":"#/components/schemas/Contact"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete contact","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contacts/bulk":{"post":{"summary":"Bulk upsert contacts (≤ 5,000 per call)","tags":["Audience"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contacts":{"type":"array","items":{"$ref":"#/components/schemas/ContactInput"}},"list_ids":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["contacts"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"imported":{"type":"integer"},"updated":{"type":"integer"},"skipped":{"type":"integer"},"suppressed":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contacts/export.csv":{"get":{"summary":"Export contacts as CSV","tags":["Audience"],"parameters":[{"name":"list_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string","description":"text/csv"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/contacts/import":{"post":{"summary":"Import CSV (Mailchimp export recognized)","tags":["Audience"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","description":"binary"},"list_id":{"type":"string","format":"uuid"},"mapping":{"type":"string","description":"JSON {csvColumn: field}"}},"required":["file"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"import":{"$ref":"#/components/schemas/Import"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/lists":{"get":{"summary":"List lists","tags":["Audience"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/List"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create list","tags":["Audience"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"double_opt_in":{"type":"boolean"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"list":{"$ref":"#/components/schemas/List"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/lists/{id}":{"get":{"summary":"Get list","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"list":{"$ref":"#/components/schemas/List"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update list","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"double_opt_in":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete list","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/lists/{id}/contacts":{"post":{"summary":"Add contacts to list","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string"}},"contact_ids":{"type":"array","items":{"type":"string","format":"uuid"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Remove contacts from list","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contact_ids":{"type":"array","items":{"type":"string","format":"uuid"}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tags":{"get":{"summary":"List tags","tags":["Audience"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Tag"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create tag","tags":["Audience"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"tag":{"$ref":"#/components/schemas/Tag"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tags/{id}":{"delete":{"summary":"Delete tag","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/tags/{id}/contacts":{"post":{"summary":"Tag contacts","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"contact_ids":{"type":"array","items":{"type":"string","format":"uuid"}}},"required":["contact_ids"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/segments":{"get":{"summary":"List segments","tags":["Audience"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Segment"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create segment","tags":["Audience"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"rules":{"$ref":"#/components/schemas/SegmentRules"}},"required":["name","rules"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"segment":{"$ref":"#/components/schemas/Segment"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/segments/{id}":{"get":{"summary":"Get segment","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"segment":{"$ref":"#/components/schemas/Segment"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update segment","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"rules":{"$ref":"#/components/schemas/SegmentRules"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete segment","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/segments/{id}/preview":{"get":{"summary":"Count + sample of a segment","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"sample":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/segments/preview":{"post":{"summary":"Preview rules without saving","tags":["Audience"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"rules":{"$ref":"#/components/schemas/SegmentRules"}},"required":["rules"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"sample":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/suppressions":{"get":{"summary":"Suppression list","tags":["Audience"],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"default 50, max 500"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Suppression"}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Add to suppression list","tags":["Audience"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string"}},"reason":{"type":"string","enum":["manual","import","unsubscribe"]}},"required":["emails"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/suppressions/{id}":{"delete":{"summary":"Remove from suppression list","tags":["Audience"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/suppressions/import":{"post":{"summary":"Import suppression CSV (e.g. Mailchimp unsubscribed export)","tags":["Audience"],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","description":"binary"}},"required":["file"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"added":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/forms":{"get":{"summary":"List signup forms","tags":["Forms"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Form"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create signup form","tags":["Forms"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Form"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"form":{"$ref":"#/components/schemas/Form"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/forms/{id}":{"get":{"summary":"Get form","tags":["Forms"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"form":{"$ref":"#/components/schemas/Form"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update form","tags":["Forms"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Form"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete form","tags":["Forms"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/forms/{slug}/submit":{"post":{"summary":"Public submit (no auth, CORS *)","tags":["Forms"],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"}},"required":["email"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"pending":{"type":"boolean","description":"true when double opt-in mail was sent"},"message":{"type":"string"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[]}},"/api/v1/templates":{"get":{"summary":"List templates (starters + mine)","tags":["Templates"],"parameters":[{"name":"scope","in":"query","required":false,"schema":{"type":"string","enum":["starter","mine"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Template"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Save template","tags":["Templates"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"category":{"type":"string"},"description":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"}},"required":["name","design"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"$ref":"#/components/schemas/Template"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/templates/{id}":{"get":{"summary":"Get template","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"$ref":"#/components/schemas/Template"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update template","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete template","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/templates/{id}/duplicate":{"post":{"summary":"Duplicate template into my templates","tags":["Templates"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"$ref":"#/components/schemas/Template"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/designs/render":{"post":{"summary":"Render a design to HTML/text (preview with sample merge values)","tags":["Templates"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"design":{"$ref":"#/components/schemas/Design"},"subject":{"type":"string"},"preheader":{"type":"string"},"sample":{"type":"boolean"}},"required":["design"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rendered"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ai/design":{"post":{"summary":"AI: brief → subjects, preheader, design (no campaign created)","tags":["AI"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"brief":{"type":"string"},"tone":{"type":"string"}},"required":["brief"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"subjects":{"type":"array","items":{"type":"string"}},"preheader":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ai/rewrite":{"post":{"summary":"AI: rewrite a block text with an instruction","tags":["AI"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"},"instruction":{"type":"string"}},"required":["text","instruction"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ai/subjects":{"post":{"summary":"AI: subject line suggestions","tags":["AI"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"brief":{"type":"string"},"design":{"$ref":"#/components/schemas/Design"},"n":{"type":"integer"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"subjects":{"type":"array","items":{"type":"string"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/ai/campaign":{"post":{"summary":"AI: brief → full campaign draft (optionally send/schedule) — the one-liner","tags":["AI"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiCampaignInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiCampaignOutput"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns":{"get":{"summary":"List campaigns","tags":["Campaigns"],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"default 50, max 500"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Campaign"}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create campaign draft","tags":["Campaigns"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}":{"get":{"summary":"Get campaign","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update draft","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CampaignInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete draft/canceled campaign","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/estimate":{"get":{"summary":"Recipients, cost and balance check","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Estimate"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/send":{"post":{"summary":"Send now or schedule (reserves recipients × unit price) (admin)","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scheduled_at":{"type":"string","format":"date-time","description":"Omit to send now"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/pause":{"post":{"summary":"Pause sending (admin)","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/resume":{"post":{"summary":"Resume sending (admin)","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/cancel":{"post":{"summary":"Cancel (refunds unsent reservation) (admin)","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/test":{"post":{"summary":"Send test to addresses (charged per send)","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"to":{"type":"array","items":{"type":"string"}}},"required":["to"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/preview":{"get":{"summary":"Rendered HTML/text with sample merge values","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Rendered"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/report":{"get":{"summary":"Report: counts, rates, links, timeline","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Report"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/recipients":{"get":{"summary":"Per-recipient delivery status","tags":["Campaigns"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"default 50, max 500"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Delivery"}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/send":{"post":{"summary":"Send a single email now (transactional or one-off; charged per send)","tags":["Send"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendInput"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"delivery_id":{"type":"integer"},"token":{"type":"string"},"cost_krw":{"type":"number"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/deliveries/{token}":{"get":{"summary":"Delivery status by token","tags":["Send"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"delivery":{"$ref":"#/components/schemas/Delivery"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/domains":{"get":{"summary":"Sending domains","tags":["Domains"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Domain"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Add sending domain → DNS records to add (admin)","tags":["Domains"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string"}},"required":["domain"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"$ref":"#/components/schemas/Domain"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/domains/{id}/verify":{"post":{"summary":"Check DNS and mark verified (admin)","tags":["Domains"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"$ref":"#/components/schemas/Domain"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/domains/{id}":{"delete":{"summary":"Remove sending domain (admin)","tags":["Domains"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/automations":{"get":{"summary":"List automations","tags":["Automations"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Automation"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create automation (welcome series)","tags":["Automations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Automation"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"automation":{"$ref":"#/components/schemas/Automation"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/automations/{id}":{"get":{"summary":"Get automation","tags":["Automations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"automation":{"$ref":"#/components/schemas/Automation"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update automation","tags":["Automations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Automation"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete automation","tags":["Automations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/automations/{id}/toggle":{"post":{"summary":"Activate/pause","tags":["Automations"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["active","paused"]}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/events":{"get":{"summary":"Raw events (open/click/bounce/…)","tags":["Reports"],"parameters":[{"name":"campaign_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}},{"name":"type","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"},"description":"default 50, max 500"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Event"}},"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/reports/overview":{"get":{"summary":"Workspace-wide daily sends/opens/clicks/cost","tags":["Reports"],"parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string"}},{"name":"to","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"days":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"sends":{"type":"integer"},"opens":{"type":"integer"},"clicks":{"type":"integer"},"cost_krw":{"type":"number"}}}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/approvals":{"get":{"summary":"Campaigns awaiting approval (with estimate + approval_url) (admin)","tags":["Autopilot"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Approval"}},"total":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/approve":{"post":{"summary":"Approve awaiting campaign → send now or at scheduled_at (admin)","tags":["Autopilot"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"scheduled_at":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/campaigns/{id}/reject":{"post":{"summary":"Reject awaiting campaign → back to draft with note (admin)","tags":["Autopilot"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"note":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/a/{token}":{"get":{"summary":"One-click approval page (HTML, no login): summary + preview; token expires after approve/reject","tags":["Autopilot"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string","description":"text/html"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[]},"post":{"summary":"Approval page form action: approve | approve_suggested | reject","tags":["Autopilot"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["approve","approve_suggested","reject"]},"note":{"type":"string"}},"required":["action"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"string","description":"text/html"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[]}},"/api/v1/autopilot/settings":{"get":{"summary":"Autopilot mode, guardrails, approval emails","tags":["Autopilot"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotSettings"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update autopilot settings (admin)","tags":["Autopilot"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotSettings"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotSettings"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/autopilot/plans":{"get":{"summary":"Recurring autopilot plans","tags":["Autopilot"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AutopilotPlan"}},"total":{"type":"integer"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"summary":"Create plan (cadence + brief template + sources + audience) (admin)","tags":["Autopilot"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotPlan"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/AutopilotPlan"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/autopilot/plans/{id}":{"get":{"summary":"Plan with campaign history","tags":["Autopilot"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/AutopilotPlan"},"history":{"type":"array","items":{"$ref":"#/components/schemas/Campaign"}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"summary":"Update plan (status: active|paused to pause/resume) (admin)","tags":["Autopilot"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutopilotPlan"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"$ref":"#/components/schemas/AutopilotPlan"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"summary":"Delete plan (admin)","tags":["Autopilot"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/autopilot/plans/{id}/run":{"post":{"summary":"Run plan now → campaign (awaiting_approval or sent per mode) (admin)","tags":["Autopilot"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/Campaign"},"status":{"type":"string"},"approval_url":{"type":"string"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/autopilot/feed":{"post":{"summary":"Preview an RSS feed as plan source","tags":["Autopilot"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"link":{"type":"string"},"published_at":{"type":"string","format":"date-time"},"summary":{"type":"string"}}}}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/learning":{"get":{"summary":"Learning memo, best hours, stats, recent insights","tags":["Learning"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Learning"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/learning/recompute":{"post":{"summary":"Recompute insights + memo now (admin)","tags":["Learning"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Learning"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Admin role required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/learning/next-suggestions":{"post":{"summary":"Suggestions for the next campaign (subjects, send time, CTA)","tags":["Learning"],"parameters":[{"name":"campaign_id","in":"query","required":false,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NextSuggestions"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing/invalid API key or session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/webhooks/sendgrid":{"post":{"summary":"SendGrid Event Webhook receiver (internal · legacy)","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[]}},"/api/webhooks/ses":{"post":{"summary":"Amazon SES event receiver via SNS HTTPS subscription (internal)","tags":["Webhooks"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"security":[]}}}}