{"openapi":"3.1.0","info":{"title":"browsertodo API","version":"0.4.0"},"servers":[{"url":"/"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key (bt_...), the ADMIN_KEY, or a session token (bt_s_...) from POST /v1/auth/google. The dashboard may instead send the bt_session cookie; cookie POST/PATCH/DELETE requests need X-Requested-With: browsertodo."}},"schemas":{"AccountSettings":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"reportEmailEnabled":{"type":"boolean"}},"required":["reportEmailEnabled"]},"BillingPlansResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"plans":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","enum":["free","starter","plus","pro"]},"name":{"type":"string"},"priceCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"creditCents":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"apiKeys":{"type":"boolean"},"voice":{"type":"boolean"},"todo":{"type":"boolean"}},"required":["id","name","priceCents","creditCents","apiKeys","voice","todo"]}},"topups":{"type":"array","items":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}}},"required":["plans","topups"]},"CheckoutInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"plan":{"type":"string","enum":["starter","plus","pro"]},"returnUrl":{"type":"string","minLength":1,"maxLength":2000}},"required":["plan","returnUrl"]},"CreditInfo":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"subscriptionCents":{"type":"number"},"topupCents":{"type":"number"},"totalCents":{"type":"number"},"periodGrantCents":{"type":"number"},"periodEnd":{"type":["string","null"]}},"required":["subscriptionCents","topupCents","totalCents","periodGrantCents","periodEnd"]},"DeleteAccountInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"confirm":{"type":"string","minLength":1}},"required":["confirm"]},"JevProxyInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"state":{},"questions":{"type":"object","propertyNames":{"type":"string"},"additionalProperties":{}}},"required":["state","questions"]},"MeBillingResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"plan":{"type":"object","properties":{"id":{"type":"string","enum":["free","starter","plus","pro"]},"status":{"type":"string","enum":["active","past_due","canceled","none"]},"currentPeriodEnd":{"type":["string","null"]},"cancelAtPeriodEnd":{"type":"boolean"}},"required":["id","status","currentPeriodEnd","cancelAtPeriodEnd"]},"credit":{"type":"object","properties":{"subscriptionCents":{"type":"number"},"topupCents":{"type":"number"},"totalCents":{"type":"number"},"periodGrantCents":{"type":"number"},"periodEnd":{"type":["string","null"]}},"required":["subscriptionCents","topupCents","totalCents","periodGrantCents","periodEnd"]},"stripeConfigured":{"type":"boolean"}},"required":["plan","credit","stripeConfigured"]},"MeResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":["string","null"]},"pictureUrl":{"type":["string","null"]},"plan":{"type":"object","properties":{"id":{"type":"string","enum":["free","starter","plus","pro"]},"status":{"type":"string","enum":["active","past_due","canceled","none"]},"currentPeriodEnd":{"type":["string","null"]},"cancelAtPeriodEnd":{"type":"boolean"}},"required":["id","status","currentPeriodEnd","cancelAtPeriodEnd"]},"credit":{"type":"object","properties":{"subscriptionCents":{"type":"number"},"topupCents":{"type":"number"},"totalCents":{"type":"number"},"periodGrantCents":{"type":"number"},"periodEnd":{"type":["string","null"]}},"required":["subscriptionCents","topupCents","totalCents","periodGrantCents","periodEnd"]}},"required":["id","email","name","pictureUrl","plan","credit"]},"OutOfCreditError":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"string","const":"out_of_credit"},"message":{"type":"string"},"topupUrl":{"type":"string"}},"required":["error","message","topupUrl"]},"PlanInfo":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string","enum":["free","starter","plus","pro"]},"status":{"type":"string","enum":["active","past_due","canceled","none"]},"currentPeriodEnd":{"type":["string","null"]},"cancelAtPeriodEnd":{"type":"boolean"}},"required":["id","status","currentPeriodEnd","cancelAtPeriodEnd"]},"PlanRequiredError":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"string","const":"plan_required"},"feature":{"type":"string","enum":["todo","voice","apiKeys"]},"message":{"type":"string"},"upgradeUrl":{"type":"string"}},"required":["error","feature","message","upgradeUrl"]},"PortalInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"returnUrl":{"type":"string","minLength":1,"maxLength":2000}},"required":["returnUrl"]},"RedirectUrlResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"SessionList":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"sessions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"createdAt":{"type":"string"},"lastUsedAt":{"type":"string"},"expiresAt":{"type":"string"},"current":{"type":"boolean"}},"required":["id","createdAt","lastUsedAt","expiresAt","current"]}}},"required":["sessions"]},"TopupInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"amountCents":{"type":"number","enum":[1000,2500,5000]},"returnUrl":{"type":"string","minLength":1,"maxLength":2000}},"required":["amountCents","returnUrl"]},"TranscribeResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"text":{"type":"string"},"seconds":{"type":"number"},"chargedCents":{"type":"number"}},"required":["text","seconds","chargedCents"]},"UsageReport":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"month":{"type":"string"},"months":{"type":"array","items":{"type":"string"}},"totals":{"type":"object","properties":{"tasksRun":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"tasksDone":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"tasksFailed":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"tasksPaused":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"aiRequests":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"inputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"outputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"chargedCents":{"type":"number"},"creditGrantedCents":{"type":"number"},"topupsCents":{"type":"number"},"audioSeconds":{"type":"number"}},"required":["tasksRun","tasksDone","tasksFailed","tasksPaused","aiRequests","inputTokens","outputTokens","chargedCents","creditGrantedCents","topupsCents"]},"byModel":{"type":"array","items":{"type":"object","properties":{"model":{"type":"string"},"requests":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"inputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"outputTokens":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"chargedCents":{"type":"number"},"audioSeconds":{"type":"number"}},"required":["model","requests","inputTokens","outputTokens","chargedCents"]}},"byDay":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"tasksRun":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"chargedCents":{"type":"number"}},"required":["date","tasksRun","chargedCents"]}}},"required":["month","months","totals","byModel","byDay"]},"ApiError":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"error":{"type":"string"},"details":{}},"required":["error"]},"AuthGoogleInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"idToken":{"type":"string","minLength":1,"maxLength":8192},"cookie":{"type":"boolean"}},"required":["idToken"]},"AuthResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"token":{"type":"string"},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":["string","null"]},"pictureUrl":{"type":["string","null"]}},"required":["id","email","name","pictureUrl"]},"expiresAt":{"type":"string"}},"required":["token","user","expiresAt"]},"BatchCreateInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tasks":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"object","properties":{"instructions":{"type":"string","minLength":1,"maxLength":8000},"account":{"type":"string","minLength":1,"maxLength":100},"mediaIds":{"maxItems":10,"type":"array","items":{"type":"string","minLength":1}},"notBefore":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"priority":{"type":"integer","minimum":-1000,"maximum":1000},"repeat":{"anyOf":[{"type":"object","properties":{"dailyAt":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"required":["dailyAt"]},{"type":"null"}]},"tz":{"anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]}},"required":["instructions"]}}},"required":["tasks"]},"ClaimInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"runnerId":{"type":"string","minLength":1,"maxLength":100}},"required":["runnerId"]},"ClaimResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"task":{"type":"object","properties":{"id":{"type":"string"},"instructions":{"type":"string"},"account":{"type":["string","null"]},"mediaIds":{"type":"array","items":{"type":"string"}},"notBefore":{"type":["string","null"]},"priority":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["pending","running","done","failed","paused","cancelled"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"leaseOwner":{"type":["string","null"]},"leaseExpiresAt":{"type":["string","null"]},"retryAfter":{"type":["string","null"]},"resultSummary":{"type":["string","null"]},"resultUrl":{"type":["string","null"]},"resultScreenshotId":{"type":["string","null"]},"pauseReason":{"type":["string","null"]},"failReason":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"repeat":{"anyOf":[{"type":"object","properties":{"dailyAt":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"required":["dailyAt"]},{"type":"null"}]},"tz":{"type":["string","null"]},"ownerId":{"type":["string","null"]}},"required":["id","instructions","account","mediaIds","notBefore","priority","status","attempts","leaseOwner","leaseExpiresAt","retryAfter","resultSummary","resultUrl","resultScreenshotId","pauseReason","failReason","createdAt","updatedAt"]},"media":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"contentType":{"type":"string"},"size":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","filename","contentType","size"]}},"leaseExpiresAt":{"type":"string"}},"required":["task","media","leaseExpiresAt"]},"CreateKeyInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"role":{"type":"string","enum":["creator","runner"]}},"required":["name","role"]},"CreateOwnKeyInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"role":{"type":"string","enum":["creator","runner"]}},"required":["name","role"]},"CreateTaskInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"instructions":{"type":"string","minLength":1,"maxLength":8000},"account":{"type":"string","minLength":1,"maxLength":100},"mediaIds":{"maxItems":10,"type":"array","items":{"type":"string","minLength":1}},"notBefore":{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},"priority":{"type":"integer","minimum":-1000,"maximum":1000},"repeat":{"anyOf":[{"type":"object","properties":{"dailyAt":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"required":["dailyAt"]},{"type":"null"}]},"tz":{"anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]}},"required":["instructions"]},"HeartbeatInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"runnerId":{"type":"string","minLength":1}},"required":["runnerId"]},"MediaInfo":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"filename":{"type":"string"},"contentType":{"type":"string"},"size":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["id","filename","contentType","size"]},"RepeatRule":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"dailyAt":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"required":["dailyAt"]},"ResultInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"runnerId":{"type":"string","minLength":1},"outcome":{"type":"string","enum":["done","failed","paused","retry"]},"summary":{"type":"string","maxLength":4000},"url":{"type":"string","maxLength":2000},"reason":{"type":"string","maxLength":4000},"screenshotId":{"type":"string"},"retryAfterMinutes":{"type":"integer","minimum":1,"maximum":1440}},"required":["runnerId","outcome"]},"Task":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"instructions":{"type":"string"},"account":{"type":["string","null"]},"mediaIds":{"type":"array","items":{"type":"string"}},"notBefore":{"type":["string","null"]},"priority":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["pending","running","done","failed","paused","cancelled"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"leaseOwner":{"type":["string","null"]},"leaseExpiresAt":{"type":["string","null"]},"retryAfter":{"type":["string","null"]},"resultSummary":{"type":["string","null"]},"resultUrl":{"type":["string","null"]},"resultScreenshotId":{"type":["string","null"]},"pauseReason":{"type":["string","null"]},"failReason":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"repeat":{"anyOf":[{"type":"object","properties":{"dailyAt":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"required":["dailyAt"]},{"type":"null"}]},"tz":{"type":["string","null"]},"ownerId":{"type":["string","null"]}},"required":["id","instructions","account","mediaIds","notBefore","priority","status","attempts","leaseOwner","leaseExpiresAt","retryAfter","resultSummary","resultUrl","resultScreenshotId","pauseReason","failReason","createdAt","updatedAt"]},"TaskEvent":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"taskId":{"type":"string"},"type":{"type":"string","enum":["created","updated","claimed","heartbeat","done","failed","paused","cancelled","retried","lease_expired"]},"detail":{"type":["string","null"]},"createdAt":{"type":"string"}},"required":["id","taskId","type","detail","createdAt"]},"TaskListResponse":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"tasks":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"instructions":{"type":"string"},"account":{"type":["string","null"]},"mediaIds":{"type":"array","items":{"type":"string"}},"notBefore":{"type":["string","null"]},"priority":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"status":{"type":"string","enum":["pending","running","done","failed","paused","cancelled"]},"attempts":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991},"leaseOwner":{"type":["string","null"]},"leaseExpiresAt":{"type":["string","null"]},"retryAfter":{"type":["string","null"]},"resultSummary":{"type":["string","null"]},"resultUrl":{"type":["string","null"]},"resultScreenshotId":{"type":["string","null"]},"pauseReason":{"type":["string","null"]},"failReason":{"type":["string","null"]},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"repeat":{"anyOf":[{"type":"object","properties":{"dailyAt":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"required":["dailyAt"]},{"type":"null"}]},"tz":{"type":["string","null"]},"ownerId":{"type":["string","null"]}},"required":["id","instructions","account","mediaIds","notBefore","priority","status","attempts","leaseOwner","leaseExpiresAt","retryAfter","resultSummary","resultUrl","resultScreenshotId","pauseReason","failReason","createdAt","updatedAt"]}},"nextCursor":{"type":["string","null"]},"locked":{"type":"boolean"}},"required":["tasks","nextCursor","locked"]},"TaskStatus":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"string","enum":["pending","running","done","failed","paused","cancelled"]},"UpdateTaskInput":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"instructions":{"type":"string","minLength":1,"maxLength":8000},"account":{"anyOf":[{"type":"string","minLength":1,"maxLength":100},{"type":"null"}]},"mediaIds":{"maxItems":10,"type":"array","items":{"type":"string","minLength":1}},"notBefore":{"anyOf":[{"type":"string","format":"date-time","pattern":"^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"},{"type":"null"}]},"priority":{"type":"integer","minimum":-1000,"maximum":1000},"repeat":{"anyOf":[{"type":"object","properties":{"dailyAt":{"minItems":1,"maxItems":24,"type":"array","items":{"type":"string","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"}}},"required":["dailyAt"]},{"type":"null"}]},"tz":{"anyOf":[{"type":"string","minLength":1,"maxLength":64},{"type":"null"}]}}},"User":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":["string","null"]},"pictureUrl":{"type":["string","null"]}},"required":["id","email","name","pictureUrl"]},"KeyInfo":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["creator","runner"]},"createdAt":{"type":"string"},"revokedAt":{"type":["string","null"]},"ownerId":{"type":["string","null"],"description":"Owning user (GET /v1/keys only); null for legacy keys"}},"required":["id","name","role","createdAt","revokedAt"]}}},"paths":{"/v1/tasks":{"post":{"summary":"Create a task","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}},"404":{"description":"Unknown media id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateTaskInput"}}}}},"get":{"summary":"List tasks, newest first. Works on every plan: `locked` is true when the plan does not include the TODO list (the kept tasks are then read-only)","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"A page of tasks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskListResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/TaskStatus"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"cursor","in":"query","schema":{"type":"string"},"description":"nextCursor of the previous page"}]}},"/v1/tasks/batch":{"post":{"summary":"Create up to 100 tasks, all or nothing","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/Task"}}},"required":["tasks"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}},"404":{"description":"Unknown media id","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchCreateInput"}}}}}},"/v1/tasks/{id}":{"get":{"summary":"Get a task with its events","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"Task and events","content":{"application/json":{"schema":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/Task"},"events":{"type":"array","items":{"$ref":"#/components/schemas/TaskEvent"}}},"required":["task","events"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]},"patch":{"summary":"Edit a pending or paused task","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Not pending or paused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTaskInput"}}}}},"delete":{"summary":"Delete a task and its events (not while running)","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Running","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/tasks/{id}/cancel":{"post":{"summary":"Cancel a pending or paused task","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Not pending or paused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/tasks/{id}/retry":{"post":{"summary":"Move a failed task back to pending (attempts reset), or run a paused one now (attempts kept)","description":"Roles: creator, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"Pending again","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Not failed or paused","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/media":{"post":{"summary":"Upload a file","description":"Roles: creator, runner, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"201":{"description":"Stored","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaInfo"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}},"413":{"description":"Too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}}}},"/v1/media/{id}":{"get":{"summary":"Download a file","description":"Roles: creator, runner, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"File bytes with its content type and Content-Disposition filename"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/runner/claim":{"post":{"summary":"Claim the next due task","description":"Roles: runner, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"Claimed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimResponse"}}}},"204":{"description":"Nothing is due"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed (ApiError), or the plan does not include the TODO list (PlanRequiredError, feature \"todo\")","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/ApiError"},{"$ref":"#/components/schemas/PlanRequiredError"}]}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimInput"}}}}}},"/v1/runner/tasks/{id}/heartbeat":{"post":{"summary":"Extend the lease","description":"Roles: runner, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"New lease expiry","content":{"application/json":{"schema":{"type":"object","properties":{"leaseExpiresAt":{"type":"string"}},"required":["leaseExpiresAt"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Not running under this runner's lease","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HeartbeatInput"}}}}}},"/v1/runner/tasks/{id}/result":{"post":{"summary":"Report done, failed, paused or retry. A repeating task that ends done or failed gets its next occurrence (once).","description":"Roles: runner, user. A signed-in user (session token) and keys it owns only see its own tasks and media; legacy keys (no owner) only see owner-less tasks and media; admin sees everything. Anything outside the caller's scope answers 404.","security":[{"bearer":[]}],"responses":{"200":{"description":"Final task","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Not running under this runner's lease","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResultInput"}}}}}},"/v1/keys":{"post":{"summary":"Create a legacy (owner-less) API key (shown once)","description":"Roles: admin.","security":[{"bearer":[]}],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"},"key":{"type":"string"}},"required":["id","name","role","key"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyInput"}}}}},"get":{"summary":"List all API keys","description":"Roles: admin.","security":[{"bearer":[]}],"responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/KeyInfo"}}},"required":["keys"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/keys/{id}":{"delete":{"summary":"Revoke an API key","description":"Roles: admin.","security":[{"bearer":[]}],"responses":{"204":{"description":"Revoked"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/auth/google":{"post":{"summary":"Sign in with a Google ID token; returns a 60-day sliding session token","description":"Public. The ID token must be signed by Google, issued for GOOGLE_CLIENT_ID, unexpired and carry a verified email. Creates the user on first sign-in.","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthGoogleInput"}}}},"responses":{"200":{"description":"Signed in","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Invalid Google ID token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Google sign-in is not configured on this server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/auth/logout":{"post":{"summary":"Revoke the calling session","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"204":{"description":"Signed out"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/me":{"get":{"summary":"The signed-in user with plan and credit","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"User, plan and credit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"summary":"Delete the account: cancels any Stripe subscription immediately, deletes tasks, events, media, keys, sessions, usage and the user","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"Stripe could not cancel the subscription (nothing deleted)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteAccountInput"}}}}}},"/v1/me/keys":{"post":{"summary":"Create an API key scoped to the signed-in user (shown once)","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"},"key":{"type":"string"}},"required":["id","name","role","key"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"The plan does not include API keys","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanRequiredError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOwnKeyInput"}}}}},"get":{"summary":"List the signed-in user's API keys","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/KeyInfo"}}},"required":["keys"]}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/me/keys/{id}":{"delete":{"summary":"Revoke one of the signed-in user's API keys","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"204":{"description":"Revoked"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/me/billing":{"get":{"summary":"Plan, credit and whether Stripe is configured","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeBillingResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/me/usage":{"get":{"summary":"Monthly usage report (tasks by outcome, hosted AI usage, credit)","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Report","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageReport"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"month","in":"query","schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$"},"description":"YYYY-MM (UTC); default this month"}]}},"/v1/me/usage.csv":{"get":{"summary":"The month's hosted AI usage events as CSV","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"text/csv","content":{"text/csv":{"schema":{"type":"string"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"month","in":"query","schema":{"type":"string"}}]}},"/v1/me/settings":{"get":{"summary":"Account settings (monthly report email opt-in)","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSettings"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"patch":{"summary":"Change account settings","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSettings"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountSettings"}}}}}},"/v1/me/sessions":{"get":{"summary":"Signed-in devices (unexpired sessions)","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Sessions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionList"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}},"delete":{"summary":"Sign out everywhere, including this device","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"204":{"description":"Signed out"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/me/sessions/{id}":{"delete":{"summary":"Sign out one device","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"204":{"description":"Signed out"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}]}},"/v1/config":{"get":{"summary":"Public runtime config for the dashboard: { googleClientId, stripeConfigured, dashboard: true }","security":[],"responses":{"200":{"description":"Config"}}}},"/v1/billing/plans":{"get":{"summary":"Plans, top-up amounts and the hosted AI markup","security":[],"responses":{"200":{"description":"Catalog","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingPlansResponse"}}}}}}},"/v1/billing/checkout":{"post":{"summary":"Stripe Checkout for a paid plan (subscription)","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Checkout page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectUrlResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"409":{"description":"Already on a paid plan: use the portal (body has portal: true)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"Stripe error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Billing is not set up on this server yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckoutInput"}}}}}},"/v1/billing/topup":{"post":{"summary":"Stripe Checkout for a one-time credit top-up","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Checkout page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectUrlResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"Stripe error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Billing is not set up on this server yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupInput"}}}}}},"/v1/billing/portal":{"post":{"summary":"Stripe customer portal (change or cancel the plan, payment method, invoices)","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Portal page","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedirectUrlResponse"}}}},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"Stripe error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Billing is not set up on this server yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PortalInput"}}}}}},"/v1/billing/webhook":{"post":{"summary":"Stripe webhook (Stripe-Signature verified; idempotent on the event id)","security":[],"responses":{"200":{"description":"Received"},"400":{"description":"Bad signature or payload","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Webhook secret not configured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}}}},"/v1/ai/messages":{"post":{"summary":"Hosted Anthropic Messages (non-streaming), paid from credit at cost x 1.30; X-Browsertodo-Charged-Cents on success","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"Anthropic's response body, unchanged"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Out of credit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutOfCreditError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"413":{"description":"Body over 20 MB","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Too many concurrent requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Hosted AI is not set up on this server yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Anthropic Messages API request"}}}}}},"/v1/ai/jev":{"post":{"summary":"Hosted Jev (TypeSafe systemOne), paid from credit at cost x 1.30","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"TypeSafe's response body, unchanged"},"400":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Out of credit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutOfCreditError"}}}},"403":{"description":"Role not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"503":{"description":"Hosted Jev is not set up on this server yet","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JevProxyInput"}}}}}},"/v1/ai/transcribe":{"post":{"summary":"Voice input: a WAV clip to text (Workers AI speech-to-text), for plans with voice; paid from credit at cost x 1.30 per audio second","description":"Roles: user (session token).","security":[{"bearer":[]}],"responses":{"200":{"description":"The text (empty for silence), the seconds billed and the charge","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscribeResponse"}}}},"400":{"description":"Not a PCM WAV file, or a bad query parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"description":"Missing or invalid key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"402":{"description":"Out of credit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutOfCreditError"}}}},"403":{"description":"The plan does not include voice input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlanRequiredError"}}}},"413":{"description":"Over 2097152 bytes or 60 seconds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"429":{"description":"Rate limit or too many concurrent requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"502":{"description":"Workers AI failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}}},"parameters":[{"name":"language","in":"query","required":false,"schema":{"type":"string"},"description":"Language hint, e.g. en or ko (default: detected)"},{"name":"speech_ms","in":"query","required":false,"schema":{"type":"number"},"description":"Milliseconds of speech the client heard; 0 skips the model and costs nothing"},{"name":"context","in":"query","required":false,"schema":{"type":"string"},"description":"Text said just before the clip (last 300 characters are used)"}],"requestBody":{"required":true,"content":{"audio/wav":{"schema":{"type":"string","format":"binary"}}}}}},"/v1/openapi.json":{"get":{"summary":"This document","security":[],"responses":{"200":{"description":"OpenAPI 3.1 document"}}}}}}