{"openapi":"3.1.0","jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","info":{"title":"Garfunkel by GAR AI API","version":"1.0.0","description":"Pay-per-post analysis of TikTok, Instagram and X posts: transcript, translation, hook, tags, comment intent. API, CLI and MCP. Async jobs, idempotent writes, prepaid balance in dollars (amounts in integer cents, 1 credit = 1 cent): the price is set aside on submit and settled per item. Error codes: unauthorized, forbidden, not_found, invalid_request, insufficient_credits, rate_limited, idempotency_conflict, internal_error."},"servers":[{"url":"/"}],"security":[{"apiKey":[]},{"oauth":["read"]},{"supabaseSession":[]}],"tags":[{"name":"Jobs"},{"name":"Uploads"},{"name":"Results"},{"name":"Accounts"},{"name":"Chat"},{"name":"Credits"},{"name":"API keys"},{"name":"Org"},{"name":"Team"}],"paths":{"/api/v1/jobs":{"post":{"operationId":"createJob","tags":["Jobs"],"summary":"Submit posts, uploads or accounts for analysis","description":"Async: returns 202 with a job id immediately. URL/upload items set their price aside now (amounts in cents). On a short balance the job is NOT lost: it is kept in `awaiting_payment` with nothing reserved and the 402 insufficient_credits `details` carry the shortfall (PaymentRequired: required, balance, shortfall, suggested_pack, topup, job_id, checkout). Pay via POST /credits/checkout (`{credits, resume_job_id}`) and the job queues automatically; unpaid jobs are canceled after 7 days. Account items (`{account, platform?, since, max_posts?}`) start in `discovering` with nothing reserved; see /confirm. Account and URL/upload items cannot be mixed. `dry_run: true` returns per-item validation and the estimate without reserving. With `kind: \"comments\"` (second step) the items are analyzed posts (`{result_id}`) or a whole posts job (`job_id`): each item holds an exact estimate from the post's reported comment count (min(reported, max_comments)) and is charged only for comments actually fetched — the rest returns to the balance. Job and items report credits_estimated / charged / returned.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Replays with the same key and body return the original response and never double-charge; a different body → 409 idempotency_conflict.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/CreateJobRequest"},{"$ref":"#/components/schemas/CreateCommentsJobRequest"}]}}}},"responses":{"200":{"description":"Dry run: validation + estimate (posts) or exact per-post comment estimates (comments).","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/DryRunResponse"},{"$ref":"#/components/schemas/CommentsDryRunResponse"}]}}}},"202":{"description":"Job accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJobResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"insufficient_credits — job kept in awaiting_payment; details: PaymentRequired {required, balance, shortfall, suggested_pack, topup, job_id, checkout}","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listJobs","tags":["Jobs"],"summary":"List jobs (newest first)","parameters":[{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from `next_cursor`.","schema":{"type":"string","maxLength":512}},{"name":"limit","in":"query","required":false,"description":"Page size (default 50, max 200).","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{id}":{"get":{"operationId":"getJob","tags":["Jobs"],"summary":"Job status, per-status counts, cost, (account jobs) accounts + notices, and `payment` while awaiting_payment","parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{id}/items":{"get":{"operationId":"listJobItems","tags":["Jobs"],"summary":"Paginated job items","parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_…`).","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from `next_cursor`.","schema":{"type":"string","maxLength":512}},{"name":"limit","in":"query","required":false,"description":"Page size (default 50, max 200).","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["awaiting_payment","queued","fetching","processing","succeeded","failed","canceled"]}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobItemList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{id}/cancel":{"post":{"operationId":"cancelJob","tags":["Jobs"],"summary":"Cancel queued items (what was set aside for them goes back) or a job awaiting payment (nothing was reserved)","parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_…`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Replays with the same key and body return the original response and never double-charge; a different body → 409 idempotency_conflict.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelJobResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{id}/retry":{"post":{"operationId":"retryJob","tags":["Jobs"],"summary":"Retry failed items (re-estimated, re-reserved)","parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_…`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Replays with the same key and body return the original response and never double-charge; a different body → 409 idempotency_conflict.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RetryJobResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"insufficient_credits — details: PaymentRequired (job_id null: nothing is kept waiting)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"invalid_request — job is not retryable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{id}/confirm":{"post":{"operationId":"confirmJob","tags":["Jobs"],"summary":"Confirm an account job after discovery: creates items and reserves the exact estimate","description":"Only when status is `awaiting_confirmation`. Read `notices` first. Idempotent once confirmed. On a short balance the items are created but nothing is reserved: the job moves to `awaiting_payment` (402 with the shortfall) and queues once your balance covers it.","parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_…`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Replays with the same key and body return the original response and never double-charge; a different body → 409 idempotency_conflict.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmJobResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"insufficient_credits — job moved to awaiting_payment; details: PaymentRequired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"invalid_request — not an account job, still discovering, or canceled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/jobs/{id}/resume":{"post":{"operationId":"resumeJob","tags":["Jobs"],"summary":"Retry reserving a job in awaiting_payment (the Stripe webhook and grants do this automatically)","description":"Queues the job if the balance now covers it; a no-op (200, credits_reserved 0) when the job is not waiting.","parameters":[{"name":"id","in":"path","required":true,"description":"Job id (`job_…`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Replays with the same key and body return the original response and never double-charge; a different body → 409 idempotency_conflict.","schema":{"type":"string","maxLength":255}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeJobResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"insufficient_credits — still short; details: PaymentRequired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/uploads":{"post":{"operationId":"createUpload","tags":["Uploads"],"summary":"Get a presigned PUT URL for a media file (max 500 MB)","description":"PUT the bytes to `upload_url` with the returned headers, then reference `upload_id` in a job within 24h.","requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadRequest"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUploadResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/results":{"get":{"operationId":"listResults","tags":["Results"],"summary":"List and filter posts; optional full-text `q`","description":"Repeatable list params (`platform`, `format`, `theme`, `emotion`, `tone`, `hook_type`, `language`) match any of their values; different params must all match. `exclude=field:value` leaves values out. Number filters (`min_views`, `max_likes`, `min_total_engagement`, …) leave out posts without that number — uploads have no platform metrics. `sort` + `order` choose the order (posts without the value last).","parameters":[{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from `next_cursor`.","schema":{"type":"string","maxLength":512}},{"name":"limit","in":"query","required":false,"description":"Page size (default 50, max 200).","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"job_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"platform","in":"query","required":false,"description":"Repeatable: platform; `upload` = your uploaded files (any of).","schema":{"anyOf":[{"type":"string","enum":["tiktok","instagram","x","upload"]},{"maxItems":50,"type":"array","items":{"type":"string","enum":["tiktok","instagram","x","upload"]}}]},"explode":true},{"name":"tag","in":"query","required":false,"description":"Repeatable. `value` or `field:value`. All must match.","schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"explode":true},{"name":"format","in":"query","required":false,"description":"Repeatable: primary format (any of).","schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}]},"explode":true},{"name":"theme","in":"query","required":false,"description":"Repeatable: primary theme (any of).","schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}]},"explode":true},{"name":"emotion","in":"query","required":false,"description":"Repeatable: emotion (any of).","schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}]},"explode":true},{"name":"tone","in":"query","required":false,"description":"Repeatable: tone (any of).","schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}]},"explode":true},{"name":"language","in":"query","required":false,"description":"Repeatable: language (ISO 639-1) (any of).","schema":{"anyOf":[{"type":"string","minLength":2,"maxLength":20},{"maxItems":50,"type":"array","items":{"type":"string","minLength":2,"maxLength":20}}]},"explode":true},{"name":"exclude","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(format|theme|emotion|tone|hook_type|language):.+$","description":"`field:value` to leave out (format, theme, emotion, tone, hook_type, language)."},{"maxItems":50,"type":"array","items":{"type":"string","pattern":"^(format|theme|emotion|tone|hook_type|language):.+$","description":"`field:value` to leave out (format, theme, emotion, tone, hook_type, language)."}}]},"explode":true},{"name":"q","in":"query","required":false,"description":"Full-text query over summary, caption and transcript.","schema":{"type":"string","maxLength":500}},{"name":"meme","in":"query","required":false,"description":"`true`: memes only; `false`: everything else.","schema":{"type":"string","enum":["true","false"]}},{"name":"culture","in":"query","required":false,"description":"Cultural signal contains this text (signal or its description).","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"hook_type","in":"query","required":false,"description":"Repeatable: hook type (any of).","schema":{"anyOf":[{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]},{"maxItems":50,"type":"array","items":{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]}}]},"explode":true},{"name":"has_comments","in":"query","required":false,"description":"`true`: posts with a comment analysis; `false`: the rest.","schema":{"type":"string","enum":["true","false"]}},{"name":"has_transcript","in":"query","required":false,"description":"`true`: posts with a transcript; `false`: the rest.","schema":{"type":"string","enum":["true","false"]}},{"name":"author","in":"query","required":false,"description":"Only posts by this account handle (case-insensitive, \"@\" optional).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"posted_after","in":"query","required":false,"description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}"}},{"name":"posted_before","in":"query","required":false,"description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}"}},{"name":"min_views","in":"query","required":false,"description":"At least this many views. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_views","in":"query","required":false,"description":"At most this many views. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_likes","in":"query","required":false,"description":"At least this many likes. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_likes","in":"query","required":false,"description":"At most this many likes. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_comments","in":"query","required":false,"description":"At least this many comments. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_comments","in":"query","required":false,"description":"At most this many comments. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_shares","in":"query","required":false,"description":"At least this many shares. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_shares","in":"query","required":false,"description":"At most this many shares. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_total_engagement","in":"query","required":false,"description":"At least this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_total_engagement","in":"query","required":false,"description":"At most this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_engagement","in":"query","required":false,"description":"At least this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_engagement","in":"query","required":false,"description":"At most this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"sort","in":"query","required":false,"description":"`newest` (default): most recently analyzed first. `posted`, `views`, `likes`, `comments`, `shares`, `saves`, `total_engagement` (likes + comments + shares), `engagement` (that ÷ views), `duration`: by that value; posts without it (uploads have no platform numbers) come last in either order. Ignored with `q`.","schema":{"type":"string","enum":["newest","posted","views","likes","comments","shares","saves","total_engagement","engagement","duration"]}},{"name":"order","in":"query","required":false,"description":"`desc` (default) or `asc`.","schema":{"type":"string","enum":["desc","asc"]}},{"name":"include","in":"query","required":false,"schema":{"type":"string","enum":["embedding"]}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/results/{item_id}":{"get":{"operationId":"getResult","tags":["Results"],"summary":"One analyzed post","parameters":[{"name":"item_id","in":"path","required":true,"description":"Item id (`itm_…`).","schema":{"type":"string"}},{"name":"include","in":"query","required":false,"description":"`embedding` to include the vector.","schema":{"type":"string","enum":["embedding"]}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Result"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteResult","tags":["Results"],"summary":"Delete one result","parameters":[{"name":"item_id","in":"path","required":true,"description":"Item id (`itm_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteResultResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/results/{item_id}/comments":{"get":{"operationId":"listComments","tags":["Results"],"summary":"Latest comment report for a post + its analyzed comments (most-liked or newest first)","description":"`report` is null until comments are analyzed (POST this path or a `kind: \"comments\"` job). Filter by `intent`, `sentiment`, `question` or `replies`; `sort=top|newest`; `thread=true` nests each top-level comment's fetched replies. `reply_stats` says how many replies existed vs were fetched.","parameters":[{"name":"item_id","in":"path","required":true,"description":"Item id (`itm_…`).","schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from `next_cursor`.","schema":{"type":"string","maxLength":512}},{"name":"limit","in":"query","required":false,"description":"Page size (default 50, max 200).","schema":{"type":"integer","minimum":1,"maximum":200}},{"name":"intent","in":"query","required":false,"schema":{"type":"string","enum":["question","complaint","praise","suggestion","humor","support","criticism","neutral","other"]}},{"name":"sentiment","in":"query","required":false,"schema":{"type":"string","enum":["very_negative","negative","neutral","positive","very_positive"]}},{"name":"include_filtered","in":"query","required":false,"description":"Include emoji-only / too-short comments (default false).","schema":{"type":"string","enum":["true","false"]}},{"name":"sort","in":"query","required":false,"description":"`top` (default): most-liked first. `newest`: latest posted first.","schema":{"type":"string","enum":["top","newest"]}},{"name":"question","in":"query","required":false,"description":"`true`: only comments that ask something (question intent or a \"?\").","schema":{"type":"string","enum":["true","false"]}},{"name":"replies","in":"query","required":false,"description":"`exclude`: top-level comments only (default include).","schema":{"type":"string","enum":["include","exclude"]}},{"name":"thread","in":"query","required":false,"description":"`true`: pages top-level comments, each with its fetched `replies` nested (filters apply to the top-level comments).","schema":{"type":"string","enum":["true","false"]}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"analyzePostComments","tags":["Results"],"summary":"Analyze (or refresh) this post's comments — a single-post comments job","description":"Second step on an analyzed post. Holds an exact estimate (min(reported comments, max_comments), 20¢ per started 100) and charges only for comments actually fetched; the rest returns automatically. `dry_run: true` returns the estimate.","parameters":[{"name":"item_id","in":"path","required":true,"description":"Item id (`itm_…`).","schema":{"type":"string"}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Replays with the same key and body return the original response and never double-charge; a different body → 409 idempotency_conflict.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":false,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyzeCommentsRequest"}}}},"responses":{"200":{"description":"Dry run.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentsDryRunResponse"}}}},"202":{"description":"Comments job accepted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJobResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"insufficient_credits","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/results/{item_id}/export":{"get":{"operationId":"exportResult","tags":["Results"],"summary":"Download one post and its comments (JSON, CSV .zip or Excel)","description":"The post (identity, url, platform, dates, metrics incl. `saves` and `total_engagement`, tags, hook with quote/source/timing, summary, what's in it, transcript lines with timestamps and translation, culture, meme, analysis notes) and the comments of its latest report (id, parent id, author, text, likes, posted time, sentiment, intent, topics). Uploads: metric fields empty, never 0.","parameters":[{"name":"item_id","in":"path","required":true,"description":"Item id (`itm_…`).","schema":{"type":"string"}},{"name":"format","in":"query","required":false,"description":"`json`: one object. `csv`: a .zip with post.csv (field,value rows) and comments.csv. `xlsx`: a workbook with \"Post\" and \"Comments\" sheets.","schema":{"default":"json","type":"string","enum":["json","csv","xlsx"]}}],"responses":{"200":{"description":"The file (Content-Disposition: attachment).","content":{"application/json":{"schema":{"type":"object"}},"application/zip":{"schema":{"type":"string","format":"binary"}},"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/results/search":{"post":{"operationId":"searchResults","tags":["Results"],"summary":"Search results","description":"Ranks the org's results by meaning and keywords. `mode: \"hybrid\"` (default) blends cosine similarity of the post embedding to the query with full-text rank; `\"semantic\"` uses similarity only; `\"full_text\"` keyword rank only. When query embeddings are unavailable the search falls back to full text and the response `mode` is `\"full_text\"`.","requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResultsRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResultsResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/results/facets":{"get":{"operationId":"getResultFacets","tags":["Results"],"summary":"What the posts are, counted: formats, themes, emotions, tones, hook types, languages, platforms, number percentiles","description":"Org-wide or for one account (`platform` + `author`). Views figures cover only posts with a view count (`with_views`); uploads have no platform metrics and are counted in `uploads`, never as zero views.","parameters":[{"name":"platform","in":"query","required":false,"schema":{"type":"string","enum":["tiktok","instagram","x","upload"]}},{"name":"author","in":"query","required":false,"description":"One account handle (case-insensitive, \"@\" optional).","schema":{"type":"string","minLength":1,"maxLength":100}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultFacets"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/saved-filters":{"get":{"operationId":"listSavedFilters","tags":["Results"],"summary":"The organization's saved filters (named filter sets for GET /results)","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedFilterList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createSavedFilter","tags":["Results"],"summary":"Save a filter set under a name (unique per organization)","requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateSavedFilterRequest"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedFilter"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/saved-filters/{id}":{"patch":{"operationId":"updateSavedFilter","tags":["Results"],"summary":"Rename a saved filter or replace its filters","parameters":[{"name":"id","in":"path","required":true,"description":"Saved filter id (`flt_…`).","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateSavedFilterRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SavedFilter"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteSavedFilter","tags":["Results"],"summary":"Delete a saved filter","parameters":[{"name":"id","in":"path","required":true,"description":"Saved filter id (`flt_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"const":true},"id":{"type":"string"}},"required":["deleted","id"]}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/accounts":{"get":{"operationId":"listAccounts","tags":["Accounts"],"summary":"Accounts the organization has analyzed or added","description":"Analyzed posts grouped by platform and author, plus accounts added with an account job. To check an account for new posts, submit an account job (`POST /jobs` with `{account, platform, since: last_posted_at}`).","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/accounts/{platform}/{handle}":{"get":{"operationId":"getAccount","tags":["Accounts"],"summary":"One account: counts, most common formats / hooks / themes / emotions, most viewed posts","parameters":[{"name":"platform","in":"path","required":true,"description":"`tiktok`, `instagram` or `x`.","schema":{"type":"string"}},{"name":"handle","in":"path","required":true,"description":"Handle, with or without \"@\" (case-insensitive).","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountDetail"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/results/export":{"get":{"operationId":"exportResults","tags":["Results"],"summary":"Stream all results as CSV or JSONL","parameters":[{"name":"job_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"platform","in":"query","required":false,"description":"Repeatable: platform; `upload` = your uploaded files (any of).","schema":{"anyOf":[{"type":"string","enum":["tiktok","instagram","x","upload"]},{"maxItems":50,"type":"array","items":{"type":"string","enum":["tiktok","instagram","x","upload"]}}]},"explode":true},{"name":"tag","in":"query","required":false,"description":"Repeatable. `value` or `field:value`. All must match.","schema":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"explode":true},{"name":"format","in":"query","required":false,"schema":{"default":"jsonl","type":"string","enum":["csv","jsonl"]}},{"name":"theme","in":"query","required":false,"description":"Repeatable: primary theme (any of).","schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}]},"explode":true},{"name":"emotion","in":"query","required":false,"description":"Repeatable: emotion (any of).","schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}]},"explode":true},{"name":"tone","in":"query","required":false,"description":"Repeatable: tone (any of).","schema":{"anyOf":[{"type":"string","minLength":1,"maxLength":200},{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}}]},"explode":true},{"name":"language","in":"query","required":false,"description":"Repeatable: language (ISO 639-1) (any of).","schema":{"anyOf":[{"type":"string","minLength":2,"maxLength":20},{"maxItems":50,"type":"array","items":{"type":"string","minLength":2,"maxLength":20}}]},"explode":true},{"name":"exclude","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(format|theme|emotion|tone|hook_type|language):.+$","description":"`field:value` to leave out (format, theme, emotion, tone, hook_type, language)."},{"maxItems":50,"type":"array","items":{"type":"string","pattern":"^(format|theme|emotion|tone|hook_type|language):.+$","description":"`field:value` to leave out (format, theme, emotion, tone, hook_type, language)."}}]},"explode":true},{"name":"meme","in":"query","required":false,"description":"`true`: memes only; `false`: everything else.","schema":{"type":"string","enum":["true","false"]}},{"name":"culture","in":"query","required":false,"description":"Cultural signal contains this text (signal or its description).","schema":{"type":"string","minLength":1,"maxLength":200}},{"name":"hook_type","in":"query","required":false,"description":"Repeatable: hook type (any of).","schema":{"anyOf":[{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]},{"maxItems":50,"type":"array","items":{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]}}]},"explode":true},{"name":"has_comments","in":"query","required":false,"description":"`true`: posts with a comment analysis; `false`: the rest.","schema":{"type":"string","enum":["true","false"]}},{"name":"has_transcript","in":"query","required":false,"description":"`true`: posts with a transcript; `false`: the rest.","schema":{"type":"string","enum":["true","false"]}},{"name":"author","in":"query","required":false,"description":"Only posts by this account handle (case-insensitive, \"@\" optional).","schema":{"type":"string","minLength":1,"maxLength":100}},{"name":"posted_after","in":"query","required":false,"description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}"}},{"name":"posted_before","in":"query","required":false,"description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed.","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}"}},{"name":"min_views","in":"query","required":false,"description":"At least this many views. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_views","in":"query","required":false,"description":"At most this many views. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_likes","in":"query","required":false,"description":"At least this many likes. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_likes","in":"query","required":false,"description":"At most this many likes. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_comments","in":"query","required":false,"description":"At least this many comments. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_comments","in":"query","required":false,"description":"At most this many comments. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_shares","in":"query","required":false,"description":"At least this many shares. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_shares","in":"query","required":false,"description":"At most this many shares. Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_total_engagement","in":"query","required":false,"description":"At least this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_total_engagement","in":"query","required":false,"description":"At most this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"min_engagement","in":"query","required":false,"description":"At least this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"max_engagement","in":"query","required":false,"description":"At most this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","schema":{"type":"number","minimum":0}},{"name":"item_id","in":"query","required":false,"description":"Repeatable: export only these posts (`itm_…`, up to 500), e.g. a selection. Filters are ignored then.","schema":{"anyOf":[{"type":"string"},{"maxItems":500,"type":"array","items":{"type":"string"}}]},"explode":true},{"name":"include","in":"query","required":false,"description":"JSONL only: add `comment_analyses` (every analyzed comment) to each line. CSV always carries comment summary columns.","schema":{"type":"string","enum":["comments"]}}],"responses":{"200":{"description":"Streamed export.","content":{"text/csv":{"schema":{"type":"string"}},"application/x-ndjson":{"schema":{"type":"string"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/data":{"delete":{"operationId":"deleteAllData","tags":["Results"],"summary":"Delete all jobs, results, uploads and chats for the organization (irreversible)","requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteDataRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteDataResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/chat":{"post":{"operationId":"chat","tags":["Chat"],"summary":"Chat with your data (streamed SSE; free, 100 questions per team per day)","description":"Free for teams with at least one tagged post: 100 questions per team per UTC day (429 `rate_limited` with `details.reason = chat_daily_limit`, `resets_at` and Retry-After at the limit; 403 `forbidden` with `details.reason = no_tagged_posts` before the first tagged post). Answers with a tool-calling analyst over the org's results (or `scope.job_ids`). Every number in the answer is validated against the tool results (one repair pass, else a safe `degraded` reply); posts are cited as `[itm_…]` and listed in `citations`. Default response is `text/event-stream` with events `thread`, `tool`, `delta` {text}, `reset` (discard the streamed draft), then `done` (ChatAnswer) or `error` (error envelope; a failed answer does not count). Send `Accept: application/json` for a single ChatAnswer. Pass `thread_id` for follow-ups.","requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatRequest"}}}},"responses":{"200":{"description":"SSE stream (default) or one ChatAnswer with `Accept: application/json`.","content":{"text/event-stream":{"schema":{"type":"string"}},"application/json":{"schema":{"$ref":"#/components/schemas/ChatAnswer"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden — details.reason no_tagged_posts: tag a post first (nothing was written)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited — details.reason chat_daily_limit: \"You've asked 100 questions today — more tomorrow.\" (nothing was written)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"chat not configured (OPENAI_API_KEY)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/chat/quota":{"get":{"operationId":"getChatQuota","tags":["Chat"],"summary":"Free chat questions used today (UTC) and the daily limit","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatQuota"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/chat/threads":{"get":{"operationId":"listChatThreads","tags":["Chat"],"summary":"Chat threads, most recently active first","parameters":[{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from `next_cursor`.","schema":{"type":"string","maxLength":512}},{"name":"limit","in":"query","required":false,"description":"Page size (default 50, max 200).","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatThreadList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/chat/threads/{id}":{"get":{"operationId":"getChatThread","tags":["Chat"],"summary":"One chat thread with its messages and citations","parameters":[{"name":"id","in":"path","required":true,"description":"Thread id (`thr_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatThreadDetail"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/credits":{"get":{"operationId":"getCredits","tags":["Credits"],"summary":"Balance (cents and dollars), packs, signup gift, invite bonus and spending rewards","description":"Amounts are integer cents (1 credit = 1 cent) with `*_usd` strings beside them (\"7.50\"). `rewards`: rolling 12-month paid spend, your cash-back tier (5% at $100+, 10% at $500+, 15% at $2,000+) and the spend to the next one.","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Credits"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/referrals":{"get":{"operationId":"getReferrals","tags":["Credits"],"summary":"Your invite link, the invite rules and the friends you invited (addresses masked)","description":"A friend who signs up through `link` and confirms their email gets +$5 on top of the $10 signup gift. You get $5 when their paid spend reaches $10 and +$10 at $25 (at most 20 rewarded invites per calendar month). Self-invites (same email, device, card or team) earn nothing.","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Referrals"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/credits/ledger":{"get":{"operationId":"listLedger","tags":["Credits"],"summary":"Append-only balance ledger in cents (newest first): purchases, gifts, rewards, holds, charges","parameters":[{"name":"cursor","in":"query","required":false,"description":"Opaque cursor from `next_cursor`.","schema":{"type":"string","maxLength":512}},{"name":"limit","in":"query","required":false,"description":"Page size (default 50, max 200).","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LedgerList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/credits/checkout":{"post":{"operationId":"createCheckout","tags":["Credits"],"summary":"Stripe Checkout URL for a pack (\"Pay $100, get $110\") or an exact top-up (agents: surface the URL to your user)","description":"Body: `{pack}` or `{credits}` (exact top-up in cents, at face value, no bonus, min 500 = $5), plus optional `resume_job_id` — a job in `awaiting_payment` that is queued first when the payment lands (the customer returns to that job page). Owners and admins (and API keys) only: members get 403 \"Only owners and admins can add money.\"","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"description":"Replays with the same key and body return the original response and never double-charge; a different body → 409 idempotency_conflict.","schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutRequest"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Stripe not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/api-keys":{"get":{"operationId":"listApiKeys","tags":["API keys"],"summary":"List API keys","security":[{"supabaseSession":[]}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createApiKey","tags":["API keys"],"summary":"Create an API key (the secret is returned once)","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedApiKey"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/api-keys/{id}":{"delete":{"operationId":"revokeApiKey","tags":["API keys"],"summary":"Revoke an API key","security":[{"supabaseSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Key id (`key_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKey"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/oauth-connections":{"get":{"operationId":"listOAuthConnections","tags":["API keys"],"summary":"Apps you connected through OAuth (MCP clients) in this organization","security":[{"supabaseSession":[]}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthConnectionList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/oauth-connections/{id}":{"delete":{"operationId":"revokeOAuthConnection","tags":["API keys"],"summary":"Disconnect an app: revokes its access and refresh tokens","security":[{"supabaseSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Connection id.","schema":{"type":"string"}}],"responses":{"204":{"description":"Revoked"},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/org":{"get":{"operationId":"getOrg","tags":["Org"],"summary":"Organization settings (name, training opt-in)","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Org"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateOrg","tags":["Org"],"summary":"Rename the organization or change the training-data opt-in (uploads only). Owners/admins.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateOrgRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Org"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team":{"get":{"operationId":"getTeam","tags":["Team"],"summary":"Your team: name, your role and what it allows, seats (\"12 of 50\"), the invite domain rule","description":"Seats are free and everyone shares one balance. Roles: owner (billing, delete team, transfer), admin (invite/remove, API keys, add money), member (tag, search, chat, export).","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateTeam","tags":["Team"],"summary":"Rename the team or set/clear \"only allow invites to @domain\". Owners/admins.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTeamRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Team"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteTeam","tags":["Team"],"summary":"Delete the team and all its data (type its name to confirm). Owners only.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteTeamRequest"}}}},"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/members":{"get":{"operationId":"listTeamMembers","tags":["Team"],"summary":"People in the team: name, email, role, joined, last active","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMemberList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"inviteTeamMember","tags":["Team"],"summary":"Add someone: emails them an invite link (single use, 7 days). Owners/admins.","description":"Role `admin` or `member` (make someone an owner after they join). Inviting an address that already has an open invite sends it again with a fresh link. Refused when the team is full (members + open invites ≥ the seat cap, 50 unless raised), over 20 invites in a day, or the address is outside the team's invite domain. The response carries the link once (it is never stored).","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInviteRequest"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedInvite"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"already in the team / team full","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/members/{id}":{"patch":{"operationId":"changeTeamRole","tags":["Team"],"summary":"Change a member's role. Owners/admins; only owners make or unmake owners; a team always keeps an owner.","security":[{"supabaseSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Member id (`usr_…`).","schema":{"type":"string"}}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMemberRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMember"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"last owner","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"removeTeamMember","tags":["Team"],"summary":"Remove someone (owners/admins; only owners remove owners). Your own id leaves the team. Their connected apps for this team stop working.","security":[{"supabaseSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Member id (`usr_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Removed."},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"last owner","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/invites":{"get":{"operationId":"listTeamInvites","tags":["Team"],"summary":"Open invites (pending or expired, not accepted or revoked). Owners/admins.","responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamInviteList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createTeamInvite","tags":["Team"],"summary":"Same as POST /team/members.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateInviteRequest"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedInvite"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/invites/{id}":{"delete":{"operationId":"revokeTeamInvite","tags":["Team"],"summary":"Revoke an open invite: its link stops working.","security":[{"supabaseSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Invite id (`inv_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked."},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/invites/{id}/resend":{"post":{"operationId":"resendTeamInvite","tags":["Team"],"summary":"Send an open invite again: a fresh link and 7 more days (counts against the daily limit).","security":[{"supabaseSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Invite id (`inv_…`).","schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedInvite"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/invites/accept":{"post":{"operationId":"acceptTeamInvite","tags":["Team"],"summary":"Join the team of an invite link (signed in, address confirmed). It becomes your active team. Joining never earns the signup gift.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInviteRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AcceptInviteResponse"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"unknown link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"expired, revoked or used","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/transfer":{"post":{"operationId":"transferTeam","tags":["Team"],"summary":"Hand the team to another member: they become owner, you become an admin. Owners only.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferTeamRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamMemberList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/team/leave":{"post":{"operationId":"leaveTeam","tags":["Team"],"summary":"Leave the team (the only owner must hand it over first; the only person deletes it instead).","security":[{"supabaseSession":[]}],"responses":{"200":{"description":"Left."},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"last owner / only person","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/teams":{"get":{"operationId":"listTeams","tags":["Team"],"summary":"Teams you are in, the active one flagged","security":[{"supabaseSession":[]}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createTeam","tags":["Team"],"summary":"Start a new team (you own it; it becomes active). Your one signup gift applies if you never had it.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTeamRequest"}}}},"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/teams/active":{"put":{"operationId":"switchTeam","tags":["Team"],"summary":"Switch your active team (remembered for you). Requests without a `garfunkel-org` header then act in it.","security":[{"supabaseSession":[]}],"requestBody":{"required":true,"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SwitchTeamRequest"}}}},"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamList"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/webhooks/secret":{"get":{"operationId":"getWebhookSecret","tags":["Org"],"summary":"Webhook signing secret: prefix and created_at only (never the secret)","security":[{"supabaseSession":[]}],"responses":{"200":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"rotateWebhookSecret","tags":["Org"],"summary":"Create or rotate the org webhook signing secret (returned once). Owners/admins.","description":"Deliveries are signed `Garfunkel-Signature: t=…,v1=…` with this `whsec_…` secret. After a rotation the previous secret also signs (a second `v1=`) for 24h.","security":[{"supabaseSession":[]}],"responses":{"201":{"description":"Successful response.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotatedWebhookSecret"}}}},"400":{"description":"invalid_request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"rate_limited (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"internal_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthorized","forbidden","not_found","invalid_request","insufficient_credits","rate_limited","idempotency_conflict","internal_error"]},"message":{"type":"string"},"details":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"retryable":{"type":"boolean"}},"required":["code","message","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"Estimate":{"type":"object","properties":{"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"breakdown":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["kind","count","credits"],"additionalProperties":false}}},"required":["credits","breakdown"],"additionalProperties":false},"CommentJobOptions":{"type":"object","properties":{"max_comments":{"default":500,"description":"Per post. Reserved credits cover min(reported comments, max_comments); you pay for comments actually fetched.","type":"integer","minimum":1,"maximum":10000},"include_replies":{"default":false,"description":"Opt-in: also fetch replies to the most-liked comments. Replies count toward max_comments (about a fifth of it is kept for replies; any unused goes back to top-level comments).","type":"boolean"},"sort":{"default":"top","description":"`top` keeps the most-liked comments when the cap cuts the thread (Instagram supports both; TikTok and X use their own ranking).","type":"string","enum":["top","recent"]}},"required":["max_comments","include_replies","sort"],"additionalProperties":false},"CreateJobRequest":{"type":"object","properties":{"items":{"minItems":1,"maxItems":1000,"type":"array","items":{"anyOf":[{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048,"description":"TikTok, Instagram or X post URL."}},"required":["url"],"additionalProperties":false},{"type":"object","properties":{"upload_id":{"type":"string","minLength":1,"maxLength":64,"description":"Id returned by POST /uploads."}},"required":["upload_id"],"additionalProperties":false},{"type":"object","properties":{"account":{"type":"string","minLength":1,"maxLength":300,"description":"\"@handle\" (with `platform`) or a profile URL (platform derived)."},"platform":{"description":"`twitter` is accepted and stored as `x`.","type":"string","enum":["tiktok","instagram","x","twitter"]},"since":{"type":"string","minLength":10,"maxLength":40,"description":"Date (YYYY-MM-DD) or timestamp: every post since then."},"max_posts":{"default":1000,"type":"integer","minimum":1,"maximum":10000}},"required":["account","since"],"additionalProperties":false}]}},"options":{"default":{"shot_detection":true,"priority":"standard"},"type":"object","properties":{"translate_to":{"description":"Translate caption, transcript and on-screen text into this language.","type":"string","pattern":"^[a-z]{2,3}(-[A-Za-z0-9]{2,8})*$"},"account_category":{"description":"Who posted, in plain words; picks the format/theme vocabulary (whole-word match with synonyms): DJ words → `dj_producer`; sports/gaming words win over \"news\" (\"sports news\" → `sports`); political words (politician, political, campaign, government, candidate, mayor, …) → `politician` unless \"news\" is present (→ `news`); then gaming, sports, news; \"producer\" alone or with music words → `dj_producer` (\"news producer\" → `news`, \"TV producer\" → `standard`); else `standard`. See `TagVocabularies`.","type":"string","minLength":1,"maxLength":64},"shot_detection":{"default":true,"description":"Hyperion pacing metrics (beta). Adds a per-item surcharge.","type":"boolean"},"priority":{"default":"standard","description":"`standard` is cheaper (batch-priced, minutes to hours); `fast` costs more credits.","type":"string","enum":["standard","fast"]},"max_credits":{"description":"Spending cap. Account jobs auto-confirm after discovery when the exact estimate is within it; other jobs are rejected if the estimate exceeds it.","type":"integer","minimum":0,"maximum":9007199254740991}},"additionalProperties":false},"webhook_url":{"anyOf":[{"type":"string","maxLength":2048,"format":"uri","description":"HTTPS URL."},{"type":"null"}]},"dry_run":{"default":false,"type":"boolean"},"metadata":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":64},"additionalProperties":{}}},"required":["items"],"additionalProperties":false},"CreateJobResponse":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"status":{"type":"string","enum":["discovering","awaiting_confirmation","awaiting_payment","queued","running","completed","canceled"]},"item_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"estimate":{"anyOf":[{"$ref":"#/components/schemas/Estimate"},{"type":"null"}],"description":"Null for account jobs until discovery finishes."},"estimate_note":{"type":"string"},"credits_reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"created_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["id","status","item_count","estimate","credits_reserved","created_at"],"additionalProperties":false},"DryRunResponse":{"type":"object","properties":{"dry_run":{"type":"boolean","const":true},"item_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"valid_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"estimate":{"anyOf":[{"$ref":"#/components/schemas/Estimate"},{"type":"null"}],"description":"Estimate over the valid items only; null for account jobs."},"estimate_note":{"type":"string"},"balance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Available credits right now."},"sufficient_credits":{"type":"boolean"},"items":{"type":"array","items":{"type":"object","properties":{"index":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"valid":{"type":"boolean"},"source":{"type":"string","enum":["url","upload","account"]},"platform":{"anyOf":[{"type":"string","enum":["tiktok","instagram","x","upload"]},{"type":"null"}]},"normalized_url":{"type":["string","null"]},"upload_id":{"type":["string","null"]},"account":{"description":"Normalized handle for account items.","type":["string","null"]},"since":{"type":["string","null"]},"price_kind":{"type":["string","null"]},"credits":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]}},"required":["index","valid","source","platform","normalized_url","upload_id","account","since","price_kind","credits","error"],"additionalProperties":false}}},"required":["dry_run","item_count","valid_count","estimate","balance","sufficient_credits","items"],"additionalProperties":false},"AccountSource":{"type":"object","properties":{"handle":{"type":"string"},"platform":{"type":"string","enum":["tiktok","instagram","x"]},"since":{"type":"string","description":"RFC 3339 timestamp."},"max_posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["queued","discovering","discovered","failed"]},"posts_found":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"oldest_post_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"reached_since":{"description":"false when the platform stopped returning posts before `since`.","type":["boolean","null"]},"stop_reason":{"type":["string","null"]},"failure_code":{"type":["string","null"]}},"required":["handle","platform","since","max_posts","status","posts_found","oldest_post_at","reached_since","stop_reason","failure_code"],"additionalProperties":false},"CreditPack":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","description":"\"Pay $100, get $110\"."},"credits":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"Balance added, in cents (1 credit = 1 cent), bonus included."},"price_cents":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991,"description":"What you pay, in cents."},"currency":{"type":"string","minLength":3,"maxLength":3},"price_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","description":"What you pay (\"100.00\")."},"value_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","description":"Balance you get, bonus included (\"110.00\")."},"bonus_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"credits − price_cents: the pack bonus."},"bonus_pct":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Bonus as a whole percent of the price (10 for +10%)."}},"required":["id","name","credits","price_cents","currency","price_usd","value_usd","bonus_cents","bonus_pct"],"additionalProperties":false},"Topup":{"type":"object","properties":{"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Exact top-up: the shortfall at list price (1 credit = 1 cent, no bonus), at least 500."},"price_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string","minLength":3,"maxLength":3}},"required":["credits","price_cents","currency"],"additionalProperties":false},"PaymentRequired":{"type":"object","properties":{"required":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Credits the job needs reserved."},"balance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Available credits right now."},"shortfall":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"required − balance."},"suggested_pack":{"anyOf":[{"$ref":"#/components/schemas/CreditPack"},{"type":"null"}],"description":"Smallest pack whose credits cover the shortfall (else the largest)."},"topup":{"$ref":"#/components/schemas/Topup"},"job_id":{"anyOf":[{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},{"type":"null"}],"description":"The job kept in `awaiting_payment` (null for a retry shortfall, where nothing is kept)."},"expires_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}],"description":"When the waiting job is canceled if still unpaid (7 days)."},"checkout_available":{"type":"boolean","description":"false when Stripe Checkout is not configured on this server."},"checkout":{"type":"object","properties":{"method":{"type":"string","const":"POST"},"path":{"type":"string"},"body":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["method","path","body"],"additionalProperties":false,"description":"Call this to get a `checkout_url` for the exact top-up; the job queues automatically once paid."}},"required":["required","balance","shortfall","suggested_pack","topup","job_id","expires_at","checkout_available","checkout"],"additionalProperties":false},"RunBy":{"type":"object","properties":{"kind":{"type":"string","enum":["person","api_key"]},"name":{"type":"string","description":"Display name (a person's name, or the API key's name)."},"email":{"description":"The person's address (people only).","type":["string","null"]}},"required":["kind","name","email"],"additionalProperties":false},"Job":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"kind":{"type":"string","enum":["posts","comments"],"description":"`posts` analyze posts; `comments` analyze comments of already-analyzed posts (second step)."},"status":{"type":"string","enum":["discovering","awaiting_confirmation","awaiting_payment","queued","running","completed","canceled"]},"item_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"counts":{"type":"object","propertyNames":{"type":"string","enum":["awaiting_payment","queued","fetching","processing","succeeded","failed","canceled"]},"additionalProperties":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"required":["awaiting_payment","queued","fetching","processing","succeeded","failed","canceled"]},"estimate":{"anyOf":[{"$ref":"#/components/schemas/Estimate"},{"type":"null"}]},"credits_reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Currently held for in-flight items."},"credits_charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits_refunded":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Reservations released for failed or canceled items."},"credits_estimated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Everything held for this job (the estimate). Receipt: estimated = charged + returned + still held."},"credits_returned":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Returned to your balance: unused estimate of finished items (reserved − charged) and all of failed/canceled ones."},"options":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"webhook_url":{"type":["string","null"]},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"completed_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"run_by":{"anyOf":[{"$ref":"#/components/schemas/RunBy"},{"type":"null"}],"description":"Who ran it: the person (web, CLI, connected app) or the API key. Null for jobs from before teams."},"accounts":{"type":"array","items":{"$ref":"#/components/schemas/AccountSource"},"description":"Account jobs only; empty otherwise."},"notices":{"type":"array","items":{"type":"string"},"description":"Human-readable warnings to read before confirming, e.g. accounts whose posts don't reach back to `since`."},"payment":{"anyOf":[{"$ref":"#/components/schemas/PaymentRequired"},{"type":"null"}],"description":"Set while status is `awaiting_payment`: what the job needs and how to cover it. Nothing is reserved until it is paid."}},"required":["id","kind","status","item_count","counts","estimate","credits_reserved","credits_charged","credits_refunded","credits_estimated","credits_returned","options","webhook_url","metadata","created_at","completed_at","run_by","accounts","notices","payment"],"additionalProperties":false},"JobSummary":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"kind":{"type":"string","enum":["posts","comments"],"description":"`posts` analyze posts; `comments` analyze comments of already-analyzed posts (second step)."},"status":{"type":"string","enum":["discovering","awaiting_confirmation","awaiting_payment","queued","running","completed","canceled"]},"item_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"estimate":{"anyOf":[{"$ref":"#/components/schemas/Estimate"},{"type":"null"}]},"options":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"webhook_url":{"type":["string","null"]},"metadata":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"completed_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"run_by":{"anyOf":[{"$ref":"#/components/schemas/RunBy"},{"type":"null"}],"description":"Who ran it: the person (web, CLI, connected app) or the API key. Null for jobs from before teams."}},"required":["id","kind","status","item_count","estimate","options","webhook_url","metadata","created_at","completed_at","run_by"],"additionalProperties":false},"JobList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/JobSummary"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"],"additionalProperties":false},"JobItem":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `itm_` prefix.","examples":["itm_0192f1d0c7a87b5e9a0c3f6e1d2b4a5a"]},"job_id":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"ordinal":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"source":{"type":"string","enum":["url","upload","result"],"description":"`result`: a comments-job item targeting an analyzed post."},"url":{"type":["string","null"]},"upload_id":{"type":["string","null"]},"result_id":{"anyOf":[{"type":"string","description":"Public id with the `itm_` prefix.","examples":["itm_0192f1d0c7a87b5e9a0c3f6e1d2b4a5a"]},{"type":"null"}],"description":"Comments jobs: the analyzed post (its item id) whose comments this item analyzes."},"platform":{"anyOf":[{"type":"string","enum":["tiktok","instagram","x","upload"]},{"type":"null"}]},"status":{"type":"string","enum":["awaiting_payment","queued","fetching","processing","succeeded","failed","canceled"]},"failure_code":{"type":["string","null"]},"failure_message":{"type":["string","null"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"price_kind":{"type":["string","null"]},"credits_reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits_charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits_estimated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Same as credits_reserved: what was held at submit."},"credits_returned":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Returned to your balance once the item finished (estimated − charged; all of it on failure)."},"comments_reported":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Comments jobs: the platform's comment count at estimate time."},"comments_requested":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Comments jobs: min(reported, max_comments) — what the estimate covers."},"comments_fetched":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Comments jobs: comments actually retrieved (what you pay for)."},"comments_analyzed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"Comments jobs: distinct comments sent to the model (after filters and exact duplicates)."},"comments_stop_reason":{"anyOf":[{"type":"string","enum":["end_of_feed","provider_limit","max_comments","post_unavailable","replies_not_fetched"]},{"type":"null"}],"description":"Why fetching stopped."},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"updated_at":{"type":"string","description":"RFC 3339 timestamp."},"finished_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]}},"required":["id","job_id","ordinal","source","url","upload_id","result_id","platform","status","failure_code","failure_message","attempts","price_kind","credits_reserved","credits_charged","credits_estimated","credits_returned","comments_reported","comments_requested","comments_fetched","comments_analyzed","comments_stop_reason","created_at","updated_at","finished_at"],"additionalProperties":false},"CreateCommentsJobRequest":{"type":"object","properties":{"kind":{"type":"string","const":"comments"},"items":{"minItems":1,"maxItems":1000,"type":"array","items":{"type":"object","properties":{"result_id":{"type":"string","description":"An analyzed post (`itm_…` from a posts job).","examples":["itm_0192f1d0c7a87b5e9a0c3f6e1d2b4a5a"]}},"required":["result_id"],"additionalProperties":false}},"job_id":{"description":"Analyze comments for every succeeded post of this posts job.","type":"string","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"options":{"default":{"max_comments":500,"include_replies":false,"sort":"top"},"$ref":"#/components/schemas/CommentJobOptions"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2048,"format":"uri"},{"type":"null"}]},"dry_run":{"default":false,"type":"boolean"},"metadata":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":64},"additionalProperties":{}}},"required":["kind"],"additionalProperties":false},"AnalyzeCommentsRequest":{"type":"object","properties":{"options":{"default":{"max_comments":500,"include_replies":false,"sort":"top"},"$ref":"#/components/schemas/CommentJobOptions"},"dry_run":{"default":false,"type":"boolean"},"webhook_url":{"anyOf":[{"type":"string","maxLength":2048,"format":"uri"},{"type":"null"}]}},"additionalProperties":false},"CommentsDryRunResponse":{"type":"object","properties":{"dry_run":{"type":"boolean","const":true},"kind":{"type":"string","const":"comments"},"item_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"valid_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"estimate":{"$ref":"#/components/schemas/Estimate"},"balance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"sufficient_credits":{"type":"boolean"},"items":{"type":"array","items":{"type":"object","properties":{"result_id":{"type":"string"},"platform":{"anyOf":[{"type":"string","enum":["tiktok","instagram","x","upload"]},{"type":"null"}]},"comments_reported":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"The platform's comment count for the post (null if unknown)."},"comments_requested":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}],"description":"min(reported, max_comments); max_comments when the count is unknown."},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"error":{"anyOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"additionalProperties":false},{"type":"null"}]}},"required":["result_id","platform","comments_reported","comments_requested","credits","error"],"additionalProperties":false}},"note":{"type":"string"}},"required":["dry_run","kind","item_count","valid_count","estimate","balance","sufficient_credits","items","note"],"additionalProperties":false},"JobItemList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/JobItem"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"],"additionalProperties":false},"CancelJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/Job"},"canceled_items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits_released":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["job","canceled_items","credits_released"],"additionalProperties":false},"ConfirmJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/Job"},"credits_reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["job","credits_reserved"],"additionalProperties":false},"ResumeJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/Job"},"credits_reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Reserved by this call (0 when the job was no longer waiting)."}},"required":["job","credits_reserved"],"additionalProperties":false},"RetryJobResponse":{"type":"object","properties":{"job":{"$ref":"#/components/schemas/Job"},"retried_items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"estimate":{"$ref":"#/components/schemas/Estimate"},"credits_reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["job","retried_items","estimate","credits_reserved"],"additionalProperties":false},"CreateUploadRequest":{"type":"object","properties":{"filename":{"type":"string","minLength":1,"maxLength":255},"content_type":{"type":"string","enum":["video/mp4","video/quicktime","video/webm","image/jpeg","image/png","image/webp"]},"size_bytes":{"type":"integer","minimum":1,"maximum":524288000,"description":"At most 500 MB."}},"required":["filename","content_type","size_bytes"],"additionalProperties":false},"CreateUploadResponse":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `upl_` prefix.","examples":["upl_0192f1d0c7a87b5e9a0c3f6e1d2b4a5b"]},"upload_url":{"type":"string","description":"Presigned PUT URL. Send the bytes with the same Content-Type and Content-Length."},"method":{"type":"string","const":"PUT"},"headers":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"string"},"description":"Headers the PUT must carry."},"expires_at":{"type":"string","description":"When the presigned URL stops working."},"attach_by":{"type":"string","description":"Uploads not attached to a job by then are deleted."}},"required":["id","upload_url","method","headers","expires_at","attach_by"],"additionalProperties":false},"CommentSummary":{"type":"object","properties":{"fetched":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Comments fetched and analyzed (what was billed)."},"total_reported":{"description":"Total comments the platform reports for the post.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"truncated":{"description":"More comments existed than max_comments allowed.","type":"boolean"},"total":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"analyzed":{"description":"Distinct comments sent to the model.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"filtered":{"description":"Emoji-only, mention-only or too-short comments.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"duplicates":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"unscored":{"description":"Comments the model could not analyze after retries; excluded from the distributions.","type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"sentiment_distribution":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"avg_score":{"description":"Mean of the per-comment scores (each an integer 1 = very negative … 5 = very positive).","type":["number","null"]},"net_sentiment":{"description":"(positive − negative) / scored, −1 to 1.","type":["number","null"]},"intent_distribution":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"top_topics":{"type":"array","items":{"type":"object","properties":{"topic":{"type":"string"},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"examples":{"type":"array","items":{"type":"string"}}},"required":["topic","count","examples"],"additionalProperties":false}},"questions":{"type":"array","items":{"type":"object","properties":{"comment_id":{"type":"string"},"text":{"type":"string"},"likes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["comment_id","text","likes"],"additionalProperties":false}},"complaints":{"type":"array","items":{"type":"object","properties":{"comment_id":{"type":"string"},"text":{"type":"string"},"likes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["comment_id","text","likes"],"additionalProperties":false}},"suggestions":{"type":"array","items":{"type":"object","properties":{"comment_id":{"type":"string"},"text":{"type":"string"},"likes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["comment_id","text","likes"],"additionalProperties":false}},"entities":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["name","count"],"additionalProperties":false}},"coordination":{"description":"Clusters of near-identical comments (possible bots or brigading).","type":"object","properties":{"clusters":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"share":{"type":"number"},"evaluated":{"type":"boolean"}},"required":["clusters","share","evaluated"],"additionalProperties":false},"notable":{"type":"array","items":{"type":"object","properties":{"comment_id":{"type":"string"},"reason":{"type":"string"}},"required":["comment_id","reason"],"additionalProperties":false}},"scoring_method":{"description":"\"llm_label\": scores are the LLM sentiment label (older reports may read \"ssr\").","type":"string"},"stop_reason":{"type":"string","enum":["end_of_feed","provider_limit","max_comments","post_unavailable","replies_not_fetched"]},"report_id":{"description":"The comments-job item that produced this report (latest one shown).","type":"string"},"analyzed_at":{"type":"string"}},"required":["fetched"],"additionalProperties":{}},"CommentAnalysis":{"type":"object","properties":{"comment_id":{"type":"string"},"parent_id":{"type":["string","null"]},"text":{"type":"string"},"author":{"type":"object","properties":{"handle":{"type":"string"},"display_name":{"type":["string","null"]},"verified":{"type":"boolean"}},"additionalProperties":false},"likes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reply_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"posted_at":{"type":["string","null"]},"lang":{"type":["string","null"]},"sentiment_score":{"type":["number","null"]},"sentiment_label":{"anyOf":[{"type":"string","enum":["very_negative","negative","neutral","positive","very_positive"]},{"type":"null"}]},"intent":{"type":["string","null"]},"topics":{"type":"array","items":{"type":"string"}},"entities":{"type":"array","items":{"type":"string"}},"filtered_reason":{"type":["string","null"]},"duplicate_of":{"type":["string","null"]},"coordination_cluster":{"type":["string","null"]}},"required":["comment_id","parent_id","text","author","likes","reply_count","posted_at","lang","sentiment_score","sentiment_label","intent","topics","entities","filtered_reason","duplicate_of","coordination_cluster"],"additionalProperties":false},"CommentReceipt":{"type":"object","properties":{"job_id":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"status":{"type":"string","enum":["awaiting_payment","queued","fetching","processing","succeeded","failed","canceled"]},"credits_estimated":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits_charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"credits_returned":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"comments_reported":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"comments_requested":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"comments_fetched":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"comments_analyzed":{"anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"comments_stop_reason":{"anyOf":[{"type":"string","enum":["end_of_feed","provider_limit","max_comments","post_unavailable","replies_not_fetched"]},{"type":"null"}]}},"required":["job_id","status","credits_estimated","credits_charged","credits_returned","comments_reported","comments_requested","comments_fetched","comments_analyzed","comments_stop_reason"],"additionalProperties":false},"ThreadedComment":{"type":"object","properties":{"comment_id":{"type":"string"},"parent_id":{"type":["string","null"]},"text":{"type":"string"},"author":{"type":"object","properties":{"handle":{"type":"string"},"display_name":{"type":["string","null"]},"verified":{"type":"boolean"}},"additionalProperties":false},"likes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"reply_count":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"posted_at":{"type":["string","null"]},"lang":{"type":["string","null"]},"sentiment_score":{"type":["number","null"]},"sentiment_label":{"anyOf":[{"type":"string","enum":["very_negative","negative","neutral","positive","very_positive"]},{"type":"null"}]},"intent":{"type":["string","null"]},"topics":{"type":"array","items":{"type":"string"}},"entities":{"type":"array","items":{"type":"string"}},"filtered_reason":{"type":["string","null"]},"duplicate_of":{"type":["string","null"]},"coordination_cluster":{"type":["string","null"]},"replies":{"description":"With `thread=true`: the fetched replies to this comment (most-liked first, ≤ 50).","type":"array","items":{"$ref":"#/components/schemas/CommentAnalysis"}}},"required":["comment_id","parent_id","text","author","likes","reply_count","posted_at","lang","sentiment_score","sentiment_label","intent","topics","entities","filtered_reason","duplicate_of","coordination_cluster"],"additionalProperties":false},"CommentReplyStats":{"type":"object","properties":{"top_level":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Top-level comments fetched."},"replies_fetched":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Replies fetched."},"replies_reported":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Replies the fetched top-level comments say they have."}},"required":["top_level","replies_fetched","replies_reported"],"additionalProperties":false},"CommentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ThreadedComment"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"},"reply_stats":{"description":"Comments vs replies in the latest report (null before any report).","anyOf":[{"$ref":"#/components/schemas/CommentReplyStats"},{"type":"null"}]},"report":{"anyOf":[{"$ref":"#/components/schemas/CommentSummary"},{"type":"null"}],"description":"Latest comment report for the post (null if never analyzed)."},"receipt":{"anyOf":[{"$ref":"#/components/schemas/CommentReceipt"},{"type":"null"}],"description":"What the latest report cost: estimated vs charged; the difference was returned."}},"required":["data","next_cursor","has_more","report","receipt"],"additionalProperties":false},"StandardFormat":{"type":"string","enum":["Tutorial","Explainer","Story","Commentary","Review","Interview","Performance","Reaction","Behind-the-Scenes","Vlog","Announcement","Challenge","Transformation","Compilation","Event","POV","ASMR"]},"PoliticianFormat":{"type":"string","enum":["Campaign Message","Policy Explainer","Rally Speech","Street Outreach","Press Conference","Debate Moment","Media Appearance","Rapid Response","Endorsement","Community Event","Behind-the-Campaign","Constituent Service","Victory Announcement","Personal Story","Call-to-Action"]},"GamingFormat":{"type":"string","enum":["Gameplay Clip","Trailer","Showcase","Announcement","Comedy Sketch","Tutorial","Player Feature","Behind-the-Scenes","Comparison","POV","Reaction","Data Reveal","Montage","Teaser","Developer Commentary","Challenge","Transformation","Gaming Meme"]},"SportsFormat":{"type":"string","enum":["Game Highlight","Player Interview","Press Conference","Team Speech","Arrival Showcase","Practice Drill","Sideline Footage","Fan Reaction","Behind-the-Scenes","Announcement","Challenge","Reaction","Event Coverage","Comedy Sketch","Vlog","Compilation","POV","Sports Meme"]},"NewsFormat":{"type":"string","enum":["Breaking News","News Explainer","Live Report","News Recap","Fact Check","Investigation Reveal","News Interview","Data Story","Analysis","Eyewitness Footage","Statement Coverage","Timeline","Side-by-Side","News Alert"]},"DjProducerFormat":{"type":"string","enum":["Production Process","DJ Performance","Music Showcase","Gear Demo","Track Breakdown","Tutorial","Transformation","Reaction","Behind-the-Scenes","Vlog","Challenge","Announcement","Meme"]},"StandardTheme":{"type":"string","enum":["Gaming","Music","Film & TV","Pop Culture","Lifestyle","Fashion","Food","Health","Technology","Education","Business","Travel","Home","Sports","News","Social","Spiritual","Creative Arts"]},"PoliticianTheme":{"type":"string","enum":["Economy","Housing","Healthcare","Education","Transportation","Public Safety","Immigration","Environment","Social Justice","Foreign Policy","Government Reform","Community Issues"]},"GamingTheme":{"type":"string","enum":["Gameplay","Competition","Story","Customization","Community","Updates","Technical","Nostalgia","Partnerships","Humor"]},"SportsTheme":{"type":"string","enum":["Competition","Performance","Team Culture","Fan Experience","Achievement","Personality","Style","Analysis","Community","Journey"]},"NewsTheme":{"type":"string","enum":["Politics","Crime & Justice","Economy","International","Weather & Disasters","Health & Science","Technology","Local News","Entertainment & Culture","Education","Military & Defense","Environment","Social Issues","Transportation"]},"DjProducerTheme":{"type":"string","enum":["Music Production","Performance","Equipment","Technique","Industry","Scene & Culture","Collaboration","Lifestyle"]},"Emotion":{"type":"string","enum":["Joy","Laughter","Inspiration","Surprise","Sadness","Fear","Anger","Love","Nostalgia","Pride","Curiosity","Cringe","FOMO","Confidence","Wholesomeness"]},"Tone":{"type":"string","enum":["Casual","Humorous","Serious","Educational","Inspirational","Energetic","Calm","Sarcastic","Dramatic","Empathetic","Critical","Mysterious","Sassy","Vulnerable","Unhinged"]},"ResultTags":{"type":"object","properties":{"format":{"anyOf":[{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/StandardFormat"},{"$ref":"#/components/schemas/PoliticianFormat"},{"$ref":"#/components/schemas/GamingFormat"},{"$ref":"#/components/schemas/SportsFormat"},{"$ref":"#/components/schemas/NewsFormat"},{"$ref":"#/components/schemas/DjProducerFormat"}],"description":"One value of the post’s account vocabulary (union of the six)."},{"type":"string","const":"Other"}]},{"type":"null"}],"description":"Primary format. `Other` when nothing in the vocabulary fits (see `format_other`)."},"format_other":{"description":"Short label for a primary `Other` format; null otherwise.","type":["string","null"]},"formats":{"type":"array","items":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/StandardFormat"},{"$ref":"#/components/schemas/PoliticianFormat"},{"$ref":"#/components/schemas/GamingFormat"},{"$ref":"#/components/schemas/SportsFormat"},{"$ref":"#/components/schemas/NewsFormat"},{"$ref":"#/components/schemas/DjProducerFormat"}],"description":"One value of the post’s account vocabulary (union of the six)."},{"type":"string","const":"Other"}]},"description":"Primary format as a list (always one value)."},"secondary_formats":{"maxItems":1,"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/StandardFormat"},{"$ref":"#/components/schemas/PoliticianFormat"},{"$ref":"#/components/schemas/GamingFormat"},{"$ref":"#/components/schemas/SportsFormat"},{"$ref":"#/components/schemas/NewsFormat"},{"$ref":"#/components/schemas/DjProducerFormat"}],"description":"One value of the post’s account vocabulary (union of the six)."},"description":"Secondary format, or empty when there is none."},"theme":{"anyOf":[{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/StandardTheme"},{"$ref":"#/components/schemas/PoliticianTheme"},{"$ref":"#/components/schemas/GamingTheme"},{"$ref":"#/components/schemas/SportsTheme"},{"$ref":"#/components/schemas/NewsTheme"},{"$ref":"#/components/schemas/DjProducerTheme"}],"description":"One value of the post’s account vocabulary (union of the six)."},{"type":"string","const":"Other"}]},{"type":"null"}],"description":"Primary theme. `Other` when nothing fits (see `theme_other`)."},"theme_other":{"description":"Short label for a primary `Other` theme; null otherwise.","type":["string","null"]},"themes":{"type":"array","items":{"anyOf":[{"anyOf":[{"$ref":"#/components/schemas/StandardTheme"},{"$ref":"#/components/schemas/PoliticianTheme"},{"$ref":"#/components/schemas/GamingTheme"},{"$ref":"#/components/schemas/SportsTheme"},{"$ref":"#/components/schemas/NewsTheme"},{"$ref":"#/components/schemas/DjProducerTheme"}],"description":"One value of the post’s account vocabulary (union of the six)."},{"type":"string","const":"Other"}]},"description":"Primary theme as a list (always one value)."},"secondary_themes":{"maxItems":1,"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/StandardTheme"},{"$ref":"#/components/schemas/PoliticianTheme"},{"$ref":"#/components/schemas/GamingTheme"},{"$ref":"#/components/schemas/SportsTheme"},{"$ref":"#/components/schemas/NewsTheme"},{"$ref":"#/components/schemas/DjProducerTheme"}],"description":"One value of the post’s account vocabulary (union of the six)."},"description":"Secondary theme, or empty when there is none."},"emotions":{"maxItems":3,"type":"array","items":{"$ref":"#/components/schemas/Emotion"},"description":"1–3 emotions, strongest first."},"tone":{"maxItems":3,"type":"array","items":{"$ref":"#/components/schemas/Tone"},"description":"1–3 tones."},"visual_elements":{"type":"array","items":{"type":"string"},"description":"Visible objects (free text, ≤ 20, each ≤ 120 chars)."},"actions":{"type":"array","items":{"type":"string"},"description":"Observable activity (free text, ≤ 20, each ≤ 120 chars)."},"setting":{"type":"array","items":{"type":"string"},"description":"Environment / occasion (free text, ≤ 20, each ≤ 120 chars)."},"technical":{"type":"array","items":{"type":"string"},"description":"Production and editing (free text, ≤ 20, each ≤ 120 chars)."},"topics":{"type":"array","items":{"type":"string"},"description":"Broader subjects (free text, ≤ 20, each ≤ 120 chars)."},"keywords":{"type":"array","items":{"type":"string"},"description":"Proper nouns, products, events (free text, ≤ 20, each ≤ 120 chars)."},"subjects":{"type":"array","items":{"type":"string"},"description":"Focal people and entities (free text, ≤ 20, each ≤ 120 chars)."},"cultural":{"type":"array","items":{"type":"string"},"description":"Cultural signals (described in `culture`) (free text, ≤ 20, each ≤ 120 chars)."}},"additionalProperties":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"null"}]}},"Hook":{"type":"object","properties":{"status":{"type":"string","enum":["present","absent","uncertain"]},"type":{"anyOf":[{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]},{"type":"null"}],"description":"Null when no hook is present."},"summary":{"type":"string","description":"How the opening grabs attention (≤ 600 chars)."},"text":{"type":"string","description":"The exact words, when clearly evidenced; else empty."},"mechanisms":{"type":"array","items":{"type":"string"},"description":"Why it works (≤ 8)."},"timing_s":{"description":"When it starts, in seconds (videos with timed speech only).","type":["number","null"]},"end_s":{"description":"When it ends, in seconds.","type":["number","null"]},"audience_promise":{"description":"What the viewer is promised for staying.","type":"string"},"payoff_connection":{"description":"How the rest of the post pays it off.","type":"string"},"confidence":{"type":"string","enum":["low","medium","high"],"description":"How sure the classification is — not how good the hook is."},"uncertainties":{"type":"array","items":{"type":"string"}}},"required":["status","type","summary","text","mechanisms","timing_s","end_s","confidence"],"additionalProperties":{}},"Meme":{"type":"object","properties":{"checked":{"type":"boolean","description":"The dedicated meme check ran (the first pass saw meme cues, or the format is a meme format). Unchecked posts are not memes."},"is_meme":{"type":"boolean"},"types":{"type":"array","items":{"type":"string","enum":["POV Format","Audio Meme","Text Overlay","Green Screen","Duet Meme","Reaction Image","Trend Participation","Original Format","Reference Meme","Filter Effect","Copypasta","Transition Meme","Caption Meme","Ironic Content","Shitpost","Other"]},"description":"≤ 4."},"indicators":{"type":"array","items":{"type":"string","enum":["Viral Audio","Popular Template","Internet Reference","Ironic Tone","Exaggerated Acting","Quick Cuts","Deep Fried Effects","Inside Joke","Trending Format","Satirical Content","Absurdist Humor","Meta Commentary"]},"description":"≤ 6."},"sources":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["Music","Film","Television","Game","Book","Advertisement","Internet Culture","Other"]},"title":{"type":"string"},"creator":{"type":["string","null"]},"confidence":{"type":"string","enum":["medium","high"]}},"required":["kind","title","creator","confidence"],"additionalProperties":false},"description":"Songs, films, shows or internet jokes the meme references (≤ 3)."},"reasoning":{"type":["string","null"]}},"required":["checked","is_meme","types","indicators","sources","reasoning"],"additionalProperties":false},"Culture":{"type":"object","properties":{"signals":{"type":"array","items":{"type":"object","properties":{"signal":{"type":"string"},"description":{"description":"What it means here; null on older results.","type":["string","null"]}},"required":["signal","description"],"additionalProperties":false},"description":"Subculture, fandom, scene or community cues (≤ 20)."}},"required":["signals"],"additionalProperties":false},"ResultBrief":{"type":"object","properties":{"narrative":{"description":"How the post works as a whole (overall narrative).","type":"string"},"detailed_summary":{"type":"string"},"sequence":{"description":"Beats / slides in order.","type":"array","items":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"claims":{"description":"Claims or messages the post makes.","type":"array","items":{"type":"string"}},"intent":{"description":"What the post is trying to do."},"visible_text":{"type":"array","items":{"type":"string"}},"entities":{"type":"array","items":{"type":"string"}},"uncertainties":{"type":"array","items":{"type":"string"}}},"additionalProperties":false},"ResultSpeech":{"type":"object","properties":{"audio_present":{"description":"The media had an audio track.","type":"boolean"},"meaningful":{"description":"The transcription is clear speech; false = music, sound effects or noise (its text is not shown).","type":"boolean"},"quality":{"description":"Transcript quality flag, when the transcriber set one (e.g. `low_confidence_music_or_noise`).","type":"string"},"text":{"description":"Athena's transcription text — the fallback when `transcript` is null.","type":"string"},"segments":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"text":{"type":"string"}},"required":["start","end","text"],"additionalProperties":false}}},"additionalProperties":false},"Result":{"type":"object","properties":{"item_id":{"type":"string","description":"Public id with the `itm_` prefix.","examples":["itm_0192f1d0c7a87b5e9a0c3f6e1d2b4a5a"]},"job_id":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"source":{"type":"object","properties":{"platform":{"type":"string","enum":["tiktok","instagram","x","upload"]},"url":{"type":["string","null"]},"author":{"type":["string","null"]},"posted_at":{"type":["string","null"]},"metrics":{"description":"Public platform counts (views, likes, comments, shares, saves). Uploads have none: every value is null or absent, never 0.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["number","null"]}},{"type":"null"}]},"filename":{"description":"Uploads: the original file name.","type":["string","null"]},"duration_s":{"description":"Media length in seconds, when known (videos and uploads).","type":["number","null"]},"thumbnail_url":{"description":"WebP thumbnail, 360 px wide (never upscaled): a representative video frame or the first image. Public posts: a stable public URL (cached for a year). Uploads: a signed URL valid for at least 1 hour (fetch the result again for a fresh one). Null when the post has no visual media (text-only); absent for posts analyzed before thumbnails existed.","type":["string","null"]},"thumbnail_small_url":{"description":"The same thumbnail at 180 px wide (table rows, small cards). Same lifetime rules as `thumbnail_url`.","type":["string","null"]},"thumbnail_width":{"description":"Width in pixels of `thumbnail_url` (360 wide, or the original when narrower).","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"thumbnail_height":{"description":"Height in pixels of `thumbnail_url`.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"thumbnail_color":{"description":"Average colour of the thumbnail (`#rrggbb`), for a placeholder while it loads.","type":["string","null"]}},"required":["platform"],"additionalProperties":{}},"caption":{"type":["string","null"]},"language":{"type":["string","null"]},"transcript":{"anyOf":[{"type":"object","properties":{"text":{"type":"string"},"segments":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"text":{"type":"string"}},"required":["start","end","text"],"additionalProperties":false}}},"required":["text"],"additionalProperties":{}},{"type":"null"}]},"translation":{"anyOf":[{"type":"object","properties":{"language":{"type":"string"},"caption":{"type":["string","null"]},"transcript":{"type":["string","null"]},"on_screen_text":{"type":["string","null"]}},"required":["language"],"additionalProperties":{}},{"type":"null"}]},"summary":{"type":["string","null"]},"description":{"description":"Two or three sentences on what the post is.","type":["string","null"]},"modality":{"anyOf":[{"type":"string","enum":["video","carousel","photo","unknown"]},{"type":"null"}],"description":"What was analyzed."},"tags":{"$ref":"#/components/schemas/ResultTags"},"hook":{"anyOf":[{"$ref":"#/components/schemas/Hook"},{"type":"null"}]},"meme":{"anyOf":[{"$ref":"#/components/schemas/Meme"},{"type":"null"}],"description":"Meme check. Null only for results without an analysis."},"culture":{"anyOf":[{"$ref":"#/components/schemas/Culture"},{"type":"null"}]},"pacing":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"Hyperion shot detection (beta)."},"speech":{"description":"What the audio held (single-result reads: GET /results/{item_id}, export). Absent on list and search rows.","anyOf":[{"$ref":"#/components/schemas/ResultSpeech"},{"type":"null"}]},"brief":{"anyOf":[{"$ref":"#/components/schemas/ResultBrief"},{"type":"null"}],"description":"Athena's analysis brief: narrative, sequence, claims, intent, on-screen text, entities, uncertainties."},"comments":{"anyOf":[{"$ref":"#/components/schemas/CommentSummary"},{"type":"null"}],"description":"Latest comment analysis report, after a comments job (`POST /jobs` with `kind: comments`, or `POST /results/{item_id}/comments`); null until then."},"embedding":{"anyOf":[{"type":"object","properties":{"model":{"type":"string"},"dims":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"vector":{"description":"Only with `?include=embedding`.","type":"array","items":{"type":"number"}}},"required":["model","dims"],"additionalProperties":false},{"type":"null"}]},"credits_charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"processed_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["item_id","job_id","source","caption","language","transcript","translation","summary","description","modality","tags","hook","meme","culture","pacing","brief","comments","embedding","credits_charged","processed_at"],"additionalProperties":false},"ResultList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Result"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"],"additionalProperties":false},"PostFilter":{"type":"object","properties":{"platform":{"maxItems":4,"type":"array","items":{"type":"string","enum":["tiktok","instagram","x","upload"]}},"format":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"theme":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"emotion":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"tone":{"maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"hook_type":{"maxItems":12,"type":"array","items":{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]}},"language":{"maxItems":50,"type":"array","items":{"type":"string","minLength":2,"maxLength":20}},"exclude":{"maxItems":50,"type":"array","items":{"type":"string","pattern":"^(format|theme|emotion|tone|hook_type|language):.+$","description":"`field:value` to leave out (format, theme, emotion, tone, hook_type, language)."}},"meme":{"type":"boolean"},"has_transcript":{"type":"boolean"},"has_comments":{"type":"boolean"},"posted_after":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}","description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed."},"posted_before":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}","description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed."},"author":{"type":"string","minLength":1,"maxLength":100},"tag":{"maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"culture":{"type":"string","minLength":1,"maxLength":200},"min_views":{"description":"At least this many views. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_views":{"description":"At most this many views. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_likes":{"description":"At least this many likes. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_likes":{"description":"At most this many likes. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_comments":{"description":"At least this many comments. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_comments":{"description":"At most this many comments. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_shares":{"description":"At least this many shares. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_shares":{"description":"At most this many shares. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_total_engagement":{"description":"At least this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","type":"number","minimum":0},"max_total_engagement":{"description":"At most this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","type":"number","minimum":0},"min_engagement":{"description":"At least this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","type":"number","minimum":0},"max_engagement":{"description":"At most this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","type":"number","minimum":0}},"additionalProperties":false},"SavedFilter":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `flt_` prefix."},"name":{"type":"string"},"filters":{"$ref":"#/components/schemas/PostFilter"},"sort":{"anyOf":[{"type":"string","enum":["newest","posted","views","likes","comments","shares","saves","total_engagement","engagement","duration"],"description":"`newest` (default): most recently analyzed first. `posted`, `views`, `likes`, `comments`, `shares`, `saves`, `total_engagement` (likes + comments + shares), `engagement` (that ÷ views), `duration`: by that value; posts without it (uploads have no platform numbers) come last in either order. Ignored with `q`."},{"type":"null"}]},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"updated_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["id","name","filters","sort","created_at","updated_at"],"additionalProperties":false},"SavedFilterList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SavedFilter"}}},"required":["data"],"additionalProperties":false},"CreateSavedFilterRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"filters":{"$ref":"#/components/schemas/PostFilter"},"sort":{"anyOf":[{"type":"string","enum":["newest","posted","views","likes","comments","shares","saves","total_engagement","engagement","duration"],"description":"`newest` (default): most recently analyzed first. `posted`, `views`, `likes`, `comments`, `shares`, `saves`, `total_engagement` (likes + comments + shares), `engagement` (that ÷ views), `duration`: by that value; posts without it (uploads have no platform numbers) come last in either order. Ignored with `q`."},{"type":"null"}]}},"required":["name","filters"],"additionalProperties":false},"UpdateSavedFilterRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60},"filters":{"$ref":"#/components/schemas/PostFilter"},"sort":{"anyOf":[{"type":"string","enum":["newest","posted","views","likes","comments","shares","saves","total_engagement","engagement","duration"],"description":"`newest` (default): most recently analyzed first. `posted`, `views`, `likes`, `comments`, `shares`, `saves`, `total_engagement` (likes + comments + shares), `engagement` (that ÷ views), `duration`: by that value; posts without it (uploads have no platform numbers) come last in either order. Ignored with `q`."},{"type":"null"}]}},"additionalProperties":false},"SearchResultsRequest":{"type":"object","properties":{"query":{"type":"string","minLength":1,"maxLength":1000},"limit":{"default":20,"type":"integer","minimum":1,"maximum":100},"cursor":{"type":"string","maxLength":512},"filters":{"type":"object","properties":{"job_id":{"type":"string"},"job_ids":{"maxItems":100,"type":"array","items":{"type":"string"}},"platform":{"description":"One platform or several (any of). `upload` = your uploaded files.","anyOf":[{"type":"string","enum":["tiktok","instagram","x","upload"]},{"maxItems":4,"type":"array","items":{"type":"string","enum":["tiktok","instagram","x","upload"]}}]},"tags":{"description":"Each tag is `value` (any tag field) or `field:value` (e.g. `topics:food`). All must match.","maxItems":20,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"format":{"description":"Primary format, any of.","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"theme":{"description":"Primary theme, any of.","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"emotion":{"description":"Emotion, any of.","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"tone":{"description":"Tone, any of.","maxItems":50,"type":"array","items":{"type":"string","minLength":1,"maxLength":200}},"language":{"description":"Spoken / written language (ISO 639-1), any of.","maxItems":50,"type":"array","items":{"type":"string","minLength":2,"maxLength":20}},"exclude":{"maxItems":50,"type":"array","items":{"type":"string","pattern":"^(format|theme|emotion|tone|hook_type|language):.+$","description":"`field:value` to leave out (format, theme, emotion, tone, hook_type, language)."}},"meme":{"description":"true: memes only; false: everything else.","type":"boolean"},"culture":{"description":"Cultural signal contains this text (signal or its description).","type":"string","minLength":1,"maxLength":200},"hook_type":{"description":"Hook type(s), any of.","anyOf":[{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]},{"maxItems":12,"type":"array","items":{"type":"string","enum":["question","bold_claim","curiosity_gap","problem","demonstration","visual_surprise","pattern_interrupt","relatable_statement","story_setup","direct_address","offer","other"]}}]},"has_comments":{"description":"true: posts with a comment analysis; false: posts without one.","type":"boolean"},"has_transcript":{"description":"true: posts with spoken words transcribed; false: the rest.","type":"boolean"},"author":{"description":"Only posts by this account handle (with or without \"@\"; case-insensitive). Combine with `platform`.","type":"string","minLength":1,"maxLength":100},"posted_after":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}","description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed."},"posted_before":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}","description":"Date (YYYY-MM-DD, inclusive). Posted date; uploads use the date they were analyzed."},"min_views":{"description":"At least this many views. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_views":{"description":"At most this many views. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_likes":{"description":"At least this many likes. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_likes":{"description":"At most this many likes. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_comments":{"description":"At least this many comments. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_comments":{"description":"At most this many comments. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_shares":{"description":"At least this many shares. Posts without it (uploads) are left out.","type":"number","minimum":0},"max_shares":{"description":"At most this many shares. Posts without it (uploads) are left out.","type":"number","minimum":0},"min_total_engagement":{"description":"At least this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","type":"number","minimum":0},"max_total_engagement":{"description":"At most this many total engagement (likes + comments + shares, a count). Posts without it (uploads) are left out.","type":"number","minimum":0},"min_engagement":{"description":"At least this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","type":"number","minimum":0},"max_engagement":{"description":"At most this many engagement rate, a fraction ((likes + comments + shares) / views; 0.05 = 5%). Posts without it (uploads) are left out.","type":"number","minimum":0}},"additionalProperties":false},"mode":{"description":"`hybrid` (default): embedding similarity blended with full-text rank. `semantic`: embedding similarity only. `full_text`: keyword rank only. Falls back to `full_text` when embeddings are unavailable; the response `mode` says which ran.","type":"string","enum":["hybrid","semantic","full_text"]}},"required":["query"],"additionalProperties":false},"SearchResultsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"item_id":{"type":"string","description":"Public id with the `itm_` prefix.","examples":["itm_0192f1d0c7a87b5e9a0c3f6e1d2b4a5a"]},"job_id":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"source":{"type":"object","properties":{"platform":{"type":"string","enum":["tiktok","instagram","x","upload"]},"url":{"type":["string","null"]},"author":{"type":["string","null"]},"posted_at":{"type":["string","null"]},"metrics":{"description":"Public platform counts (views, likes, comments, shares, saves). Uploads have none: every value is null or absent, never 0.","anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{"type":["number","null"]}},{"type":"null"}]},"filename":{"description":"Uploads: the original file name.","type":["string","null"]},"duration_s":{"description":"Media length in seconds, when known (videos and uploads).","type":["number","null"]},"thumbnail_url":{"description":"WebP thumbnail, 360 px wide (never upscaled): a representative video frame or the first image. Public posts: a stable public URL (cached for a year). Uploads: a signed URL valid for at least 1 hour (fetch the result again for a fresh one). Null when the post has no visual media (text-only); absent for posts analyzed before thumbnails existed.","type":["string","null"]},"thumbnail_small_url":{"description":"The same thumbnail at 180 px wide (table rows, small cards). Same lifetime rules as `thumbnail_url`.","type":["string","null"]},"thumbnail_width":{"description":"Width in pixels of `thumbnail_url` (360 wide, or the original when narrower).","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"thumbnail_height":{"description":"Height in pixels of `thumbnail_url`.","anyOf":[{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},{"type":"null"}]},"thumbnail_color":{"description":"Average colour of the thumbnail (`#rrggbb`), for a placeholder while it loads.","type":["string","null"]}},"required":["platform"],"additionalProperties":{}},"caption":{"type":["string","null"]},"language":{"type":["string","null"]},"transcript":{"anyOf":[{"type":"object","properties":{"text":{"type":"string"},"segments":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"text":{"type":"string"}},"required":["start","end","text"],"additionalProperties":false}}},"required":["text"],"additionalProperties":{}},{"type":"null"}]},"translation":{"anyOf":[{"type":"object","properties":{"language":{"type":"string"},"caption":{"type":["string","null"]},"transcript":{"type":["string","null"]},"on_screen_text":{"type":["string","null"]}},"required":["language"],"additionalProperties":{}},{"type":"null"}]},"summary":{"type":["string","null"]},"description":{"description":"Two or three sentences on what the post is.","type":["string","null"]},"modality":{"anyOf":[{"type":"string","enum":["video","carousel","photo","unknown"]},{"type":"null"}],"description":"What was analyzed."},"tags":{"$ref":"#/components/schemas/ResultTags"},"hook":{"anyOf":[{"$ref":"#/components/schemas/Hook"},{"type":"null"}]},"meme":{"anyOf":[{"$ref":"#/components/schemas/Meme"},{"type":"null"}],"description":"Meme check. Null only for results without an analysis."},"culture":{"anyOf":[{"$ref":"#/components/schemas/Culture"},{"type":"null"}]},"pacing":{"anyOf":[{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}},{"type":"null"}],"description":"Hyperion shot detection (beta)."},"speech":{"description":"What the audio held (single-result reads: GET /results/{item_id}, export). Absent on list and search rows.","anyOf":[{"$ref":"#/components/schemas/ResultSpeech"},{"type":"null"}]},"brief":{"anyOf":[{"$ref":"#/components/schemas/ResultBrief"},{"type":"null"}],"description":"Athena's analysis brief: narrative, sequence, claims, intent, on-screen text, entities, uncertainties."},"comments":{"anyOf":[{"$ref":"#/components/schemas/CommentSummary"},{"type":"null"}],"description":"Latest comment analysis report, after a comments job (`POST /jobs` with `kind: comments`, or `POST /results/{item_id}/comments`); null until then."},"embedding":{"anyOf":[{"type":"object","properties":{"model":{"type":"string"},"dims":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"vector":{"description":"Only with `?include=embedding`.","type":"array","items":{"type":"number"}}},"required":["model","dims"],"additionalProperties":false},{"type":"null"}]},"credits_charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"processed_at":{"type":"string","description":"RFC 3339 timestamp."},"score":{"type":"number","description":"Relevance (higher is better)."}},"required":["item_id","job_id","source","caption","language","transcript","translation","summary","description","modality","tags","hook","meme","culture","pacing","brief","comments","embedding","credits_charged","processed_at","score"],"additionalProperties":false}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"},"mode":{"type":"string","enum":["hybrid","semantic","full_text"],"description":"The ranking that actually ran."}},"required":["data","next_cursor","has_more","mode"],"additionalProperties":false},"ResultFacets":{"type":"object","properties":{"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"with_views":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts that have a view count. Views figures count only these; uploads have no platform metrics."},"views_total":{"description":"Sum of views over `with_views` posts; null when none have views.","type":["number","null"]},"views_median":{"type":["number","null"]},"uploads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Your uploaded files (no platform metrics)."},"with_comments":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts with a comment analysis."},"first_posted_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"last_posted_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"last_analyzed_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"formats":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["value","posts"],"additionalProperties":false}},"themes":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["value","posts"],"additionalProperties":false}},"emotions":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["value","posts"],"additionalProperties":false}},"hooks":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["value","posts"],"additionalProperties":false},"description":"Hook types (`question`, `bold_claim`, …)."},"platforms":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["value","posts"],"additionalProperties":false}},"tones":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["value","posts"],"additionalProperties":false}},"languages":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["value","posts"],"additionalProperties":false},"description":"ISO 639-1 codes, lowercase."},"with_transcript":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts with a transcript."},"memes":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Posts the meme check found to be memes."},"metrics":{"type":"object","propertyNames":{"type":"string","enum":["views","likes","comments","shares","total_engagement","engagement"]},"additionalProperties":{"type":"object","properties":{"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"p50":{"type":"number"},"p75":{"type":"number"},"p90":{"type":"number"},"max":{"type":"number"}},"required":["posts","p50","p75","p90","max"],"additionalProperties":false},"description":"Percentiles of each platform number over the posts that have it (never uploads). `total_engagement` is likes + comments + shares; `engagement` is that ÷ views, a fraction."}},"required":["posts","with_views","views_total","views_median","uploads","with_comments","first_posted_at","last_posted_at","last_analyzed_at","formats","themes","emotions","hooks","platforms","tones","languages","with_transcript","memes","metrics"],"additionalProperties":false},"AccountSummary":{"type":"object","properties":{"platform":{"type":"string","enum":["tiktok","instagram","x"]},"handle":{"type":"string","description":"Lowercase, without \"@\"."},"display_handle":{"type":"string","description":"As the platform writes it."},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Analyzed posts."},"with_views":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"views_total":{"type":["number","null"]},"first_posted_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"last_posted_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}],"description":"Newest analyzed post: \"Check for new posts\" asks for posts after this."},"last_analyzed_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"added_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}],"description":"When the account was first added with an account job (null: only single posts were analyzed)."},"last_checked_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"checking":{"type":"boolean","description":"An account job for it is still discovering, waiting or running."},"url":{"type":"string","description":"Profile URL."}},"required":["platform","handle","display_handle","posts","with_views","views_total","first_posted_at","last_posted_at","last_analyzed_at","added_at","last_checked_at","checking","url"],"additionalProperties":false},"AccountList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AccountSummary"}}},"required":["data"],"additionalProperties":false},"AccountDetail":{"type":"object","properties":{"platform":{"type":"string","enum":["tiktok","instagram","x"]},"handle":{"type":"string","description":"Lowercase, without \"@\"."},"display_handle":{"type":"string","description":"As the platform writes it."},"posts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Analyzed posts."},"with_views":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"views_total":{"type":["number","null"]},"first_posted_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"last_posted_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}],"description":"Newest analyzed post: \"Check for new posts\" asks for posts after this."},"last_analyzed_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"added_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}],"description":"When the account was first added with an account job (null: only single posts were analyzed)."},"last_checked_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"checking":{"type":"boolean","description":"An account job for it is still discovering, waiting or running."},"url":{"type":"string","description":"Profile URL."},"stats":{"$ref":"#/components/schemas/ResultFacets"},"top_posts":{"type":"array","items":{"$ref":"#/components/schemas/Result"},"description":"Most viewed posts (only posts with a view count), up to 5."}},"required":["platform","handle","display_handle","posts","with_views","views_total","first_posted_at","last_posted_at","last_analyzed_at","added_at","last_checked_at","checking","url","stats","top_posts"],"additionalProperties":false},"DeleteResultResponse":{"type":"object","properties":{"deleted":{"type":"boolean","const":true},"item_id":{"type":"string","description":"Public id with the `itm_` prefix.","examples":["itm_0192f1d0c7a87b5e9a0c3f6e1d2b4a5a"]}},"required":["deleted","item_id"],"additionalProperties":false},"DeleteDataRequest":{"type":"object","properties":{"confirm":{"type":"boolean","const":true,"description":"Must be `true`. Deletes all jobs, results, uploads and chats for the org."}},"required":["confirm"],"additionalProperties":false},"DeleteDataResponse":{"type":"object","properties":{"deleted":{"type":"object","properties":{"jobs":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"results":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"uploads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"chat_threads":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["jobs","results","uploads","chat_threads"],"additionalProperties":false},"credits_released":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["deleted","credits_released"],"additionalProperties":false},"ChatRequest":{"type":"object","properties":{"thread_id":{"type":["string","null"]},"message":{"type":"string","minLength":1,"maxLength":8000},"scope":{"description":"New threads only: limit answers to these jobs (default: all results). A thread keeps the scope it was created with.","type":"object","properties":{"job_ids":{"maxItems":100,"type":"array","items":{"type":"string"}}}}},"required":["message"],"additionalProperties":false},"ChatScope":{"type":"object","properties":{"job_ids":{"type":"array","items":{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},"description":"Jobs the thread is limited to; empty = all of the org’s results."}},"required":["job_ids"],"additionalProperties":false},"ChatCitation":{"type":"object","properties":{"item_id":{"type":"string","description":"Public id with the `itm_` prefix.","examples":["itm_0192f1d0c7a87b5e9a0c3f6e1d2b4a5a"]},"platform":{"type":["string","null"]},"author":{"type":["string","null"]},"url":{"type":["string","null"]},"summary":{"type":["string","null"]}},"required":["item_id","platform","author","url","summary"],"additionalProperties":false},"ChatMessage":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `msg_` prefix.","examples":["msg_0192f1d0c7a87b5e9a0c3f6e1d2b4a5d"]},"role":{"type":"string","enum":["user","assistant"]},"content":{"type":"string","description":"Markdown-light text; assistant answers cite posts as `[itm_…]`."},"citations":{"type":"array","items":{"$ref":"#/components/schemas/ChatCitation"}},"validation":{"anyOf":[{"type":"string","enum":["passed","repaired","degraded"],"description":"Number check: `passed` (every figure traced to tool results), `repaired` (a draft failed and was corrected), `degraded` (no verifiable answer; a safe reply is returned and nothing is charged)."},{"type":"null"}]},"credits_charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"created_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["id","role","content","citations","validation","credits_charged","created_at"],"additionalProperties":false},"ChatThread":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `thr_` prefix.","examples":["thr_0192f1d0c7a87b5e9a0c3f6e1d2b4a5c"]},"title":{"type":["string","null"]},"scope":{"$ref":"#/components/schemas/ChatScope"},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"updated_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["id","title","scope","created_at","updated_at"],"additionalProperties":false},"ChatThreadList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ChatThread"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"],"additionalProperties":false},"ChatThreadDetail":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `thr_` prefix.","examples":["thr_0192f1d0c7a87b5e9a0c3f6e1d2b4a5c"]},"title":{"type":["string","null"]},"scope":{"$ref":"#/components/schemas/ChatScope"},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"updated_at":{"type":"string","description":"RFC 3339 timestamp."},"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}}},"required":["id","title","scope","created_at","updated_at","messages"],"additionalProperties":false},"ChatAnswer":{"type":"object","properties":{"thread_id":{"type":"string","description":"Public id with the `thr_` prefix.","examples":["thr_0192f1d0c7a87b5e9a0c3f6e1d2b4a5c"]},"user_message_id":{"type":"string","description":"Public id with the `msg_` prefix.","examples":["msg_0192f1d0c7a87b5e9a0c3f6e1d2b4a5d"]},"message":{"$ref":"#/components/schemas/ChatMessage"},"credits_reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Always 0: chat is free (kept for compatibility)."},"credits_charged":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Always 0: chat is free (kept for compatibility)."},"validation":{"type":"string","enum":["passed","repaired","degraded"],"description":"Number check: `passed` (every figure traced to tool results), `repaired` (a draft failed and was corrected), `degraded` (no verifiable answer; a safe reply is returned and nothing is charged)."},"questions_today":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Questions your team asked today (UTC), this one included."},"daily_limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Free questions per team per UTC day."}},"required":["thread_id","user_message_id","message","credits_reserved","credits_charged","validation","questions_today","daily_limit"],"additionalProperties":false},"ChatQuota":{"type":"object","properties":{"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Questions asked today (UTC day)."},"limit":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Free questions per team per day."},"remaining":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"resets_at":{"type":"string","description":"Next UTC midnight."},"eligible":{"type":"boolean","description":"false until the team has at least one tagged post (nothing to ask about yet)."}},"required":["used","limit","remaining","resets_at","eligible"],"additionalProperties":false},"SpendTier":{"type":"object","properties":{"min_spend_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Paid spend in the last 12 months that reaches this tier."},"min_spend_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pct":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cash back on each purchase, as balance."}},"required":["min_spend_cents","min_spend_usd","pct"],"additionalProperties":false},"SpendRewards":{"type":"object","properties":{"spend_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Paid spend (Stripe purchases minus refunds) in the last `window_months`; free balance never counts."},"spend_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"pct":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Your current tier: cash back on your next purchase (0 below the first tier)."},"window_months":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"next":{"anyOf":[{"type":"object","properties":{"min_spend_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"pct":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"remaining_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"remaining_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"}},"required":["min_spend_cents","pct","remaining_cents","remaining_usd"],"additionalProperties":false},{"type":"null"}],"description":"The next tier and the spend still needed to reach it; null at the top tier."},"tiers":{"type":"array","items":{"$ref":"#/components/schemas/SpendTier"}}},"required":["spend_cents","spend_usd","pct","window_months","next","tiers"],"additionalProperties":false},"Credits":{"type":"object","properties":{"balance":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Available balance in cents (1 credit = 1 cent; reservations already deducted)."},"balance_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$","description":"The same balance in dollars (\"7.50\")."},"reserved":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cents held for in-flight items."},"reserved_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"packs":{"type":"array","items":{"$ref":"#/components/schemas/CreditPack"}},"signup_grant":{"anyOf":[{"type":"object","properties":{"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cents (1000 = $10)."},"amount_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"granted_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["credits","amount_usd","granted_at"],"additionalProperties":false},{"type":"null"}],"description":"The one-time signup gift ($10 after email confirmation), or null if this org has none."},"referral_bonus":{"anyOf":[{"type":"object","properties":{"cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"amount_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"granted_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["cents","amount_usd","granted_at"],"additionalProperties":false},{"type":"null"}],"description":"The +$5 for joining through a friend's invite link, or null."},"rewards":{"$ref":"#/components/schemas/SpendRewards"},"low_balance":{"anyOf":[{"type":"object","properties":{"threshold":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Balance (cents) below which the org is nudged to top up."},"reason":{"type":"string","enum":["below_one_post","below_smallest_pack","below_last_purchase_share"]},"suggested_pack":{"anyOf":[{"$ref":"#/components/schemas/CreditPack"},{"type":"null"}]}},"required":["threshold","reason","suggested_pack"],"additionalProperties":false},{"type":"null"}],"description":"Set when the balance is below the smallest pack or below 20% of the last purchase (the `credits.low` webhook fires on the same crossing)."}},"required":["balance","balance_usd","reserved","reserved_usd","packs","signup_grant","referral_bonus","rewards","low_balance"],"additionalProperties":false},"LedgerEntry":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["purchase","grant","reserve","release","charge","refund","reward","reversal"],"description":"`reward`: spending reward or invite reward; `reversal`: a reward taken back after a refund."},"amount":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cents; positive adds to the balance."},"amount_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"job_id":{"type":["string","null"]},"item_id":{"type":["string","null"]},"note":{"type":["string","null"]},"created_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["id","kind","amount","amount_usd","job_id","item_id","note","created_at"],"additionalProperties":false},"LedgerList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/LedgerEntry"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"],"additionalProperties":false},"CheckoutRequest":{"type":"object","properties":{"pack":{"description":"A pack id from GET /credits.","type":"string","minLength":1,"maxLength":64},"credits":{"description":"Exact top-up in credits instead of a pack: 1 credit = 1 cent, no bonus, minimum 500 ($5).","type":"integer","minimum":500,"maximum":10000000},"resume_job_id":{"description":"A job in `awaiting_payment` to queue first once this payment lands.","type":"string","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]}},"additionalProperties":false},"CheckoutResponse":{"type":"object","properties":{"url":{"type":"string","description":"Stripe Checkout URL (`checkout_url`) — open it to pay."},"session_id":{"type":"string"},"pack":{"anyOf":[{"$ref":"#/components/schemas/CreditPack"},{"type":"null"}],"description":"Null for an exact top-up."},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"price_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"currency":{"type":"string","minLength":3,"maxLength":3},"resume_job_id":{"anyOf":[{"type":"string","description":"Public id with the `job_` prefix.","examples":["job_0192f1d0c7a87b5e9a0c3f6e1d2b4a59"]},{"type":"null"}]}},"required":["url","session_id","pack","credits","price_cents","currency","resume_job_id"],"additionalProperties":false},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string","description":"First 12 characters of the key, for display."},"last_used_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"revoked_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"created_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["id","name","prefix","last_used_at","revoked_at","created_at"],"additionalProperties":false},"ApiKeyList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["data"],"additionalProperties":false},"CreateApiKeyRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}},"required":["name"],"additionalProperties":false},"CreatedApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string","description":"First 12 characters of the key, for display."},"last_used_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"revoked_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"key":{"type":"string","description":"The secret. Shown once — store it now."}},"required":["id","name","prefix","last_used_at","revoked_at","created_at","key"],"additionalProperties":false},"OAuthConnection":{"type":"object","properties":{"id":{"type":"string"},"client_id":{"type":"string"},"client_name":{"type":"string"},"client_uri":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string","enum":["read","submit"]},"description":"`read`: jobs/results; `submit`: spends from the balance."},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"last_used_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]}},"required":["id","client_id","client_name","client_uri","scopes","created_at","last_used_at"],"additionalProperties":false},"OAuthConnectionList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OAuthConnection"}}},"required":["data"],"additionalProperties":false},"Org":{"type":"object","properties":{"name":{"type":"string"},"role":{"anyOf":[{"type":"string","enum":["owner","admin","member"]},{"type":"null"}],"description":"Your role (null for API keys)."},"training_opt_in":{"type":"boolean","description":"Opt-in to use frames from your **uploads** (never fetched posts) as training data."},"training_opt_in_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"training_terms_version":{"type":["string","null"]}},"required":["name","role","training_opt_in","training_opt_in_at","training_terms_version"],"additionalProperties":false},"UpdateOrgRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"training_opt_in":{"type":"boolean"}},"additionalProperties":false},"Price":{"type":"object","properties":{"kind":{"type":"string"},"credits":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Cents (75 = 75¢)."},"description":{"type":"string"}},"required":["kind","credits","description"],"additionalProperties":false},"ReferralMilestone":{"type":"object","properties":{"spend_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Your friend's paid spend that triggers it."},"reward_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["spend_cents","reward_cents"],"additionalProperties":false},"ReferralFriend":{"type":"object","properties":{"id":{"type":"string"},"email_masked":{"type":"string","description":"Never the full address (\"j•••@g•••.com\")."},"status":{"type":"string","enum":["signed_up","joined","spent_10","spent_25","not_eligible"],"description":"`signed_up`: waiting for email confirmation; `joined`: confirmed; `spent_10` / `spent_25`: paid spend reached; `not_eligible`: a self-invite."},"joined_at":{"type":"string","description":"RFC 3339 timestamp."},"earned_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"What this friend earned you so far."},"capped":{"type":"boolean","description":"A milestone landed over the monthly cap: counted, not paid."}},"required":["id","email_masked","status","joined_at","earned_cents","capped"],"additionalProperties":false},"Referrals":{"type":"object","properties":{"code":{"type":"string"},"link":{"type":"string","description":"Your invite link: {APP_URL}/r/{code}."},"friend_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"What a friend gets on top of the signup gift."},"milestones":{"type":"array","items":{"$ref":"#/components/schemas/ReferralMilestone"}},"monthly_cap":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Rewarded invites per calendar month (UTC)."},"rewarded_this_month":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"earned_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"earned_usd":{"type":"string","pattern":"^-?\\d+\\.\\d{2}$"},"friends":{"type":"array","items":{"$ref":"#/components/schemas/ReferralFriend"}}},"required":["code","link","friend_cents","milestones","monthly_cap","rewarded_this_month","earned_cents","earned_usd","friends"],"additionalProperties":false},"MoneyConfig":{"type":"object","properties":{"signup_grant_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"referral":{"type":"object","properties":{"friend_cents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"milestones":{"type":"array","items":{"$ref":"#/components/schemas/ReferralMilestone"}},"monthly_cap":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["friend_cents","milestones","monthly_cap"],"additionalProperties":false},"spend_rewards":{"type":"object","properties":{"window_months":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"tiers":{"type":"array","items":{"$ref":"#/components/schemas/SpendTier"}}},"required":["window_months","tiers"],"additionalProperties":false},"chat_daily_questions":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},"required":["signup_grant_cents","referral","spend_rewards","chat_daily_questions"],"additionalProperties":false},"WebhookSecret":{"type":"object","properties":{"configured":{"type":"boolean","description":"false until the org creates a secret (deliveries are then signed with the deployment-wide key)."},"prefix":{"description":"First 14 characters (`whsec_` + 8), for display.","type":["string","null"]},"created_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]}},"required":["configured","prefix","created_at"],"additionalProperties":false},"RotatedWebhookSecret":{"type":"object","properties":{"secret":{"type":"string","description":"`whsec_…`. Shown once — store it now. The previous secret keeps signing for 24h."},"prefix":{"type":"string"},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"previous_valid_until":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}],"description":"Until then deliveries carry a second `v1=` signature made with the previous secret."}},"required":["secret","prefix","created_at","previous_valid_until"],"additionalProperties":false},"Team":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `team_` prefix.","examples":["team_0192f1d0c7a87b5e9a0c3f6e1d2b4a70"]},"name":{"type":"string"},"role":{"anyOf":[{"type":"string","enum":["owner","admin","member"],"description":"owner: billing, delete team, transfer · admin: people, API keys, add money · member: tag, search, chat, export."},{"type":"null"}],"description":"Your role (null for API keys)."},"seats":{"type":"object","properties":{"used":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"People in the team."},"cap":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Seat cap (50 unless raised on request). Seats are free."},"pending_invites":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991,"description":"Open invites that have not expired (they hold a seat)."}},"required":["used","cap","pending_invites"],"additionalProperties":false},"invites_today":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"invites_per_day":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"invite_domain":{"description":"When set, only addresses @ this domain can be invited or join.","type":["string","null"]},"permissions":{"type":"object","properties":{"add_money":{"type":"boolean"},"manage_keys":{"type":"boolean"},"manage_people":{"type":"boolean"},"team_settings":{"type":"boolean"},"delete_data":{"type":"boolean"},"billing":{"type":"boolean"},"delete_team":{"type":"boolean"},"transfer_ownership":{"type":"boolean"}},"required":["add_money","manage_keys","manage_people","team_settings","delete_data","billing","delete_team","transfer_ownership"],"additionalProperties":false,"description":"What the caller may do in this team."}},"required":["id","name","role","seats","invites_today","invites_per_day","invite_domain","permissions"],"additionalProperties":false},"TeamMember":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `usr_` prefix.","examples":["usr_0192f1d0c7a87b5e9a0c3f6e1d2b4a71"]},"name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"],"description":"owner: billing, delete team, transfer · admin: people, API keys, add money · member: tag, search, chat, export."},"joined_at":{"type":"string","description":"RFC 3339 timestamp."},"last_active_at":{"anyOf":[{"type":"string","description":"RFC 3339 timestamp."},{"type":"null"}]},"you":{"type":"boolean"}},"required":["id","name","email","role","joined_at","last_active_at","you"],"additionalProperties":false},"TeamMemberList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TeamMember"}}},"required":["data"],"additionalProperties":false},"TeamInvite":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `inv_` prefix.","examples":["inv_0192f1d0c7a87b5e9a0c3f6e1d2b4a72"]},"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"],"description":"owner: billing, delete team, transfer · admin: people, API keys, add money · member: tag, search, chat, export."},"status":{"type":"string","enum":["pending","expired"]},"invited_by":{"description":"Name of the person who sent it.","type":["string","null"]},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"last_sent_at":{"type":"string","description":"RFC 3339 timestamp."},"expires_at":{"type":"string","description":"RFC 3339 timestamp."}},"required":["id","email","role","status","invited_by","created_at","last_sent_at","expires_at"],"additionalProperties":false},"TeamInviteList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TeamInvite"}}},"required":["data"],"additionalProperties":false},"CreateInviteRequest":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email","pattern":"^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"},"role":{"default":"member","type":"string","enum":["admin","member"]}},"required":["email"],"additionalProperties":false},"CreatedInvite":{"type":"object","properties":{"id":{"type":"string","description":"Public id with the `inv_` prefix.","examples":["inv_0192f1d0c7a87b5e9a0c3f6e1d2b4a72"]},"email":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"],"description":"owner: billing, delete team, transfer · admin: people, API keys, add money · member: tag, search, chat, export."},"status":{"type":"string","enum":["pending","expired"]},"invited_by":{"description":"Name of the person who sent it.","type":["string","null"]},"created_at":{"type":"string","description":"RFC 3339 timestamp."},"last_sent_at":{"type":"string","description":"RFC 3339 timestamp."},"expires_at":{"type":"string","description":"RFC 3339 timestamp."},"resent":{"type":"boolean","description":"true when an open invite to this address was sent again with a fresh link."},"email_sent":{"type":"boolean","description":"false when email isn't configured on this server (the link still works when shared)."},"link":{"type":"string","description":"The invite link (single use, 7 days). Only returned now: it is never stored."}},"required":["id","email","role","status","invited_by","created_at","last_sent_at","expires_at","resent","email_sent","link"],"additionalProperties":false},"UpdateMemberRequest":{"type":"object","properties":{"role":{"type":"string","enum":["owner","admin","member"],"description":"owner: billing, delete team, transfer · admin: people, API keys, add money · member: tag, search, chat, export."}},"required":["role"],"additionalProperties":false},"UpdateTeamRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"invite_domain":{"description":"Only allow invites to this domain; null turns the rule off.","anyOf":[{"type":"string","maxLength":253,"pattern":"^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$"},{"type":"null"}]}},"additionalProperties":false},"TransferTeamRequest":{"type":"object","properties":{"user_id":{"type":"string","minLength":1,"description":"The member (`usr_…`) who becomes the owner; you become an admin."}},"required":["user_id"],"additionalProperties":false},"DeleteTeamRequest":{"type":"object","properties":{"confirm_name":{"type":"string","description":"The team's name, typed to confirm."}},"required":["confirm_name"],"additionalProperties":false},"AcceptInviteRequest":{"type":"object","properties":{"token":{"type":"string","minLength":16,"maxLength":128}},"required":["token"],"additionalProperties":false},"AcceptInviteResponse":{"type":"object","properties":{"status":{"type":"string","enum":["joined","already_member"]},"team":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"],"description":"owner: billing, delete team, transfer · admin: people, API keys, add money · member: tag, search, chat, export."}},"required":["id","name","role"],"additionalProperties":false}},"required":["status","team"],"additionalProperties":false},"TeamSummary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member"],"description":"owner: billing, delete team, transfer · admin: people, API keys, add money · member: tag, search, chat, export."},"members":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"active":{"type":"boolean"}},"required":["id","name","role","members","active"],"additionalProperties":false},"TeamList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/TeamSummary"}}},"required":["data"],"additionalProperties":false},"SwitchTeamRequest":{"type":"object","properties":{"team_id":{"type":"string","minLength":1}},"required":["team_id"],"additionalProperties":false},"CreateTeamRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}},"required":["name"],"additionalProperties":false},"PostCard":{"type":"object","properties":{"item_id":{"type":"string"},"platform":{"type":"string","enum":["tiktok","instagram","x","upload"]},"url":{"type":["string","null"]},"author":{"type":["string","null"]},"language":{"type":["string","null"]},"summary":{"description":"The short description (else the first paragraph of the summary).","type":["string","null"]},"format":{"type":["string","null"]},"theme":{"type":["string","null"]},"emotions":{"type":"array","items":{"type":"string"}},"tone":{"type":"array","items":{"type":"string"}},"hook":{"anyOf":[{"type":"object","properties":{"type":{"description":"Hook type in words, e.g. \"Bold claim\".","type":["string","null"]},"text":{"description":"The exact opening words.","type":["string","null"]},"confidence":{"description":"low / medium / high: classification confidence, not quality.","type":["string","null"]}},"required":["type","text","confidence"],"additionalProperties":false},{"type":"null"}],"description":"null when the post has no hook."},"topics":{"type":"array","items":{"type":"string"}},"culture":{"type":"array","items":{"type":"string"},"description":"Culture / fandom cues the post references."},"meme":{"anyOf":[{"type":"object","properties":{"is_meme":{"type":"boolean"},"types":{"type":"array","items":{"type":"string"}},"references":{"type":"array","items":{"type":"string"},"description":"Songs, films or internet jokes it references."}},"required":["is_meme","types","references"],"additionalProperties":false},{"type":"null"}],"description":"null when the meme check is not available for this post."},"web_url":{"type":"string","description":"Open this post's job results in the Garfunkel web app."}},"required":["item_id","platform","url","author","language","summary","format","theme","emotions","tone","hook","topics","culture","meme","web_url"],"additionalProperties":false}},"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","bearerFormat":"gma_live_…","description":"Org-scoped API key."},"oauth":{"type":"oauth2","description":"OAuth 2.1 authorization code + PKCE (S256) with dynamic client registration; discovery at /.well-known/oauth-authorization-server. Tokens with only `read` may call GET endpoints; anything else needs `submit`.","flows":{"authorizationCode":{"authorizationUrl":"/oauth/authorize","tokenUrl":"/oauth/token","refreshUrl":"/oauth/token","scopes":{"read":"Read jobs and results","submit":"Submit jobs (spends from your balance)"}}}},"supabaseSession":{"type":"apiKey","in":"cookie","name":"sb-access-token","description":"Web UI session."}}}}