{"openapi":"3.1.0","info":{"title":"Amy","version":"1.0.0","description":"Amy is a personal health agent. The API exposes Amy's multi-agent reasoning pipeline over wearable + lab data. See https://docs.heyamy.xyz.","contact":{"name":"Amy","url":"https://heyamy.xyz"}},"servers":[{"url":"https://amy.heyamy.xyz","description":"Production"},{"url":"http://localhost:8787","description":"Local development"}],"tags":[{"name":"Turns","description":"The agent run loop."},{"name":"Sources","description":"Connected wearables."},{"name":"Labs","description":"Uploaded bloodwork."},{"name":"Memory","description":"What Amy remembers."},{"name":"Me","description":"The authenticated user."},{"name":"Meta","description":"OpenAPI spec, llms.txt, health."},{"name":"Webhooks","description":"Inbound ingest (Terra)."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Amy session token (30-day Amy JWT, eyJ…)"}},"schemas":{},"parameters":{}},"paths":{"/v1/turns":{"post":{"tags":["Turns"],"summary":"Start a turn","description":"Kick off a multi-agent reasoning turn. Returns 202 immediately with a turn id; subscribe to GET /v1/turns/:id/events to stream live agent output, or poll GET /v1/turns/:id for the final result.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"idempotency-key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]},"minItems":1},"stream":{"type":"boolean"},"conversation_id":{"type":"string","minLength":1,"maxLength":128},"title":{"type":"string","maxLength":200},"context":{"type":"object","properties":{"include_memory":{"type":"boolean","default":true},"include_biomarkers":{"type":"boolean","default":true}}},"deep_research":{"type":"object","properties":{"days":{"type":"integer","minimum":0,"exclusiveMinimum":true},"data_types":{"type":"array","items":{"type":"string","enum":["recovery","sleep","hrv","strain","bloodwork","food"]},"minItems":1}},"required":["days","data_types"]}},"required":["messages"]}}}},"responses":{"202":{"description":"Turn accepted; running async.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed"]},"created_at":{"type":"string","format":"date-time"},"stream_url":{"type":"string"}},"required":["id","status","created_at"]}}}},"400":{"description":"Validation failure.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"409":{"description":"idempotency-key reused with a different request body.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"429":{"description":"Concurrency cap (max 20 turns in flight per user).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"get":{"tags":["Turns"],"summary":"List turns","description":"Paginated list of turns for the authenticated user, newest first.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"string","enum":["queued","running","completed","failed"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"after","in":"query"},{"schema":{"type":"string","format":"date-time"},"required":false,"name":"before","in":"query"}],"responses":{"200":{"description":"A page of turns.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed"]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","nullable":true,"format":"date-time"},"user_message_preview":{"type":"string"},"cost_usd":{"type":"number","nullable":true},"duration_ms":{"type":"integer","nullable":true}},"required":["id","status","created_at","completed_at","user_message_preview","cost_usd","duration_ms"]}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"]}}}}}}},"/v1/turns/{id}":{"get":{"tags":["Turns"],"summary":"Get a turn","description":"Fetch the current status and (when complete) result of a turn.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The turn.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed"]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","nullable":true,"format":"date-time"},"messages":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}},"required":["role","content"]}},"result":{"type":"object","nullable":true,"properties":{"answer":{"type":"string"},"fact_sheet":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"string"}]},"unit":{"type":"string"},"window":{"type":"string"},"n":{"type":"integer"},"source":{"type":"string","enum":["investigator","data_science","domain_expert","health_coach","validator","orchestrator"]}},"required":["key","value"]}},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"claim":{"type":"string"},"kind":{"type":"string","enum":["scalar","association","trend","threshold"]},"feature":{"type":"string"},"target":{"type":"string"},"window":{"type":"string"},"effect":{"type":"number"},"n":{"type":"integer"},"p_value":{"type":"number"},"ci_low":{"type":"number"},"ci_high":{"type":"number"},"unit":{"type":"string"},"source":{"type":"string","enum":["investigator","data_science","domain_expert","health_coach","validator","orchestrator"]}},"required":["id","claim","kind"]}},"widgets":{"type":"array","items":{"type":"object","properties":{"anchor":{"type":"number"},"spec":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["stat_tiles"]},"id":{"type":"string"},"title":{"type":"string"},"tiles":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}},"delta":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"deltaFmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label","value"]},"minItems":1,"maxItems":4}},"required":["kind","id","tiles"]},{"type":"object","properties":{"kind":{"type":"string","enum":["comparison"]},"id":{"type":"string"},"title":{"type":"string"},"mode":{"type":"string","enum":["before_after","a_vs_b"]},"a":{"type":"object","properties":{"label":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label","value"]},"b":{"type":"object","properties":{"label":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label","value"]},"deltaPct":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"direction":{"type":"string","enum":["good_up","good_down","neutral"]}},"required":["kind","id","mode","a","b"]},{"type":"object","properties":{"kind":{"type":"string","enum":["series_chart"]},"id":{"type":"string"},"title":{"type":"string"},"unit":{"type":"string"},"points":{"type":"array","items":{"type":"object","properties":{"t":{"type":"string"},"y":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]}},"required":["t","y"]},"maxItems":120},"baseline":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"changepoint":{"type":"object","properties":{"index":{"type":"number"},"label":{"type":"string"}},"required":["index"]},"direction":{"type":"string","enum":["good_up","good_down"]}},"required":["kind","id","points"]},{"type":"object","properties":{"kind":{"type":"string","enum":["checklist"]},"id":{"type":"string"},"title":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"done":{"type":"boolean"}},"required":["id","text"]},"maxItems":8},"trackable":{"type":"boolean"}},"required":["kind","id","items"]},{"type":"object","properties":{"kind":{"type":"string","enum":["experiment_card"]},"id":{"type":"string"},"title":{"type":"string"},"hypothesis":{"type":"string"},"protocol":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string"},"cadence":{"type":"string"}},"required":["text"]},"maxItems":8},"metric":{"type":"object","properties":{"label":{"type":"string"},"ref":{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label"]},"durationDays":{"type":"number"},"confidence":{"type":"string","enum":["high","medium","emerging"]}},"required":["kind","id","title","protocol"]},{"type":"object","properties":{"kind":{"type":"string","enum":["investigation_summary"]},"id":{"type":"string"},"verdict":{"type":"string"},"confidence":{"type":"string","enum":["high","medium","emerging"]},"deltaHeadline":{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}},"direction":{"type":"string","enum":["good_up","good_down","neutral"]}},"required":["value"]},"evidenceRefs":{"type":"array","items":{"type":"string"}},"agentsUsed":{"type":"array","items":{"type":"string"}}},"required":["kind","id","verdict","confidence","evidenceRefs"]}]}},"required":["anchor","spec"]}},"agents_used":{"type":"array","items":{"type":"string","enum":["investigator","data_science","domain_expert","health_coach","validator","orchestrator"]}},"cost_usd":{"type":"number"},"duration_ms":{"type":"integer"},"suggest_deep_research":{"type":"boolean"}},"required":["answer","fact_sheet","agents_used","cost_usd","duration_ms"]},"error":{"type":"object","nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"},"step":{"type":"string"}},"required":["code","message"]}},"required":["id","status","created_at","completed_at","messages","result","error"]}}}},"404":{"description":"No turn with that id.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/turns/{id}/events":{"get":{"tags":["Turns"],"summary":"Stream turn events (SSE)","description":"Server-Sent Events stream of the turn's lifecycle: turn.started, phase, agent_start, agent_end, synthesis_delta, turn.completed, etc. Reconnect with Last-Event-Id to resume. See https://docs.heyamy.xyz/docs/concepts/streaming for the full event-type catalog.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":false,"name":"last-event-id","in":"header"}],"responses":{"200":{"description":"Event stream.","content":{"text/event-stream":{"schema":{"type":"string","description":"SSE wire format: event/id/data per frame."}}}},"404":{"description":"No turn with that id.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/conversations":{"get":{"tags":["Conversations"],"summary":"List conversations","description":"Paginated list of the authenticated user's conversation threads, newest activity first. A thread is the set of turns sharing a conversation_id.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"A page of conversation summaries.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"turn_count":{"type":"integer"},"preview":{"type":"string"}},"required":["id","title","created_at","updated_at","turn_count","preview"]}},"next_cursor":{"type":"string","nullable":true},"has_more":{"type":"boolean"}},"required":["data","next_cursor","has_more"]}}}}}}},"/v1/conversations/{id}":{"get":{"tags":["Conversations"],"summary":"Get a conversation","description":"Every turn in the thread, oldest first, with full results.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The thread.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"turns":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["queued","running","completed","failed"]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","nullable":true,"format":"date-time"},"user_message":{"type":"string"},"result":{"type":"object","nullable":true,"properties":{"answer":{"type":"string"},"fact_sheet":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"string"}]},"unit":{"type":"string"},"window":{"type":"string"},"n":{"type":"integer"},"source":{"type":"string","enum":["investigator","data_science","domain_expert","health_coach","validator","orchestrator"]}},"required":["key","value"]}},"evidence":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"claim":{"type":"string"},"kind":{"type":"string","enum":["scalar","association","trend","threshold"]},"feature":{"type":"string"},"target":{"type":"string"},"window":{"type":"string"},"effect":{"type":"number"},"n":{"type":"integer"},"p_value":{"type":"number"},"ci_low":{"type":"number"},"ci_high":{"type":"number"},"unit":{"type":"string"},"source":{"type":"string","enum":["investigator","data_science","domain_expert","health_coach","validator","orchestrator"]}},"required":["id","claim","kind"]}},"widgets":{"type":"array","items":{"type":"object","properties":{"anchor":{"type":"number"},"spec":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["stat_tiles"]},"id":{"type":"string"},"title":{"type":"string"},"tiles":{"type":"array","items":{"type":"object","properties":{"label":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}},"delta":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"deltaFmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label","value"]},"minItems":1,"maxItems":4}},"required":["kind","id","tiles"]},{"type":"object","properties":{"kind":{"type":"string","enum":["comparison"]},"id":{"type":"string"},"title":{"type":"string"},"mode":{"type":"string","enum":["before_after","a_vs_b"]},"a":{"type":"object","properties":{"label":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label","value"]},"b":{"type":"object","properties":{"label":{"type":"string"},"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label","value"]},"deltaPct":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"direction":{"type":"string","enum":["good_up","good_down","neutral"]}},"required":["kind","id","mode","a","b"]},{"type":"object","properties":{"kind":{"type":"string","enum":["series_chart"]},"id":{"type":"string"},"title":{"type":"string"},"unit":{"type":"string"},"points":{"type":"array","items":{"type":"object","properties":{"t":{"type":"string"},"y":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]}},"required":["t","y"]},"maxItems":120},"baseline":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"changepoint":{"type":"object","properties":{"index":{"type":"number"},"label":{"type":"string"}},"required":["index"]},"direction":{"type":"string","enum":["good_up","good_down"]}},"required":["kind","id","points"]},{"type":"object","properties":{"kind":{"type":"string","enum":["checklist"]},"id":{"type":"string"},"title":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"done":{"type":"boolean"}},"required":["id","text"]},"maxItems":8},"trackable":{"type":"boolean"}},"required":["kind","id","items"]},{"type":"object","properties":{"kind":{"type":"string","enum":["experiment_card"]},"id":{"type":"string"},"title":{"type":"string"},"hypothesis":{"type":"string"},"protocol":{"type":"array","items":{"type":"object","properties":{"text":{"type":"string"},"cadence":{"type":"string"}},"required":["text"]},"maxItems":8},"metric":{"type":"object","properties":{"label":{"type":"string"},"ref":{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}}},"required":["label"]},"durationDays":{"type":"number"},"confidence":{"type":"string","enum":["high","medium","emerging"]}},"required":["kind","id","title","protocol"]},{"type":"object","properties":{"kind":{"type":"string","enum":["investigation_summary"]},"id":{"type":"string"},"verdict":{"type":"string"},"confidence":{"type":"string","enum":["high","medium","emerging"]},"deltaHeadline":{"type":"object","properties":{"value":{"anyOf":[{"type":"number"},{"type":"object","properties":{"ref":{"type":"string"},"fallback":{"type":"number"}},"required":["ref"]}]},"fmt":{"type":"object","properties":{"unit":{"type":"string","maxLength":12},"decimals":{"type":"integer","minimum":0,"maximum":3},"sign":{"type":"boolean"}}},"direction":{"type":"string","enum":["good_up","good_down","neutral"]}},"required":["value"]},"evidenceRefs":{"type":"array","items":{"type":"string"}},"agentsUsed":{"type":"array","items":{"type":"string"}}},"required":["kind","id","verdict","confidence","evidenceRefs"]}]}},"required":["anchor","spec"]}},"agents_used":{"type":"array","items":{"type":"string","enum":["investigator","data_science","domain_expert","health_coach","validator","orchestrator"]}},"cost_usd":{"type":"number"},"duration_ms":{"type":"integer"},"suggest_deep_research":{"type":"boolean"}},"required":["answer","fact_sheet","agents_used","cost_usd","duration_ms"]},"error":{"type":"object","nullable":true,"properties":{"code":{"type":"string"},"message":{"type":"string"},"step":{"type":"string"}},"required":["code","message"]}},"required":["id","status","created_at","completed_at","user_message","result","error"]}}},"required":["id","title","created_at","updated_at","turns"]}}}},"404":{"description":"No conversation with that id.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"delete":{"tags":["Conversations"],"summary":"Delete a conversation","description":"Permanently delete every turn in the thread for the authenticated user. Idempotent — deleting an already-gone thread returns deleted: 0.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deletion result.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted":{"type":"integer"}},"required":["id","deleted"]}}}}}}},"/v1/me":{"get":{"tags":["Me"],"summary":"Get current user","description":"Returns the authenticated user's identity plus inline `connections` (connected wearables via Terra). Reconciles against Terra on every call so a fresh OAuth shows up without waiting on a webhook.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"email":{"type":"string","nullable":true,"format":"email"},"connections":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"provider":{"type":"string"},"terra_user_id":{"type":"string"},"connected_at":{"type":"string"},"deactivated_at":{"type":"string","nullable":true}},"required":["id","provider","terra_user_id","connected_at","deactivated_at"]}},"env":{"type":"string"}},"required":["user_id","email","connections","env"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"delete":{"tags":["Me"],"summary":"Delete the current account","description":"Permanently deletes the authenticated user: all wearable/lab data, Terra connections (deauthorized), chat history, profile, and the Clerk identity. Irreversible. The same email can sign up fresh afterwards.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"rows_deleted":{"type":"number"}},"required":["ok","rows_deleted"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/me/profile":{"get":{"tags":["Me"],"summary":"Get the user's health profile","description":"Returns the user-provided health profile. Fields the user hasn't set are null ('not provided') — the agent never fabricates demographics.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"name":{"type":"string","nullable":true},"age":{"type":"number","nullable":true},"gender":{"type":"string","nullable":true},"height_cm":{"type":"number","nullable":true},"weight_kg":{"type":"number","nullable":true},"bmi":{"type":"number","nullable":true},"smoker":{"type":"string","nullable":true},"alcohol_consumption":{"type":"string","nullable":true},"conditions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"duration_years":{"type":"number"}},"required":["name"]},"default":[]},"medications":{"type":"array","items":{"type":"string"},"default":[]},"goal":{"type":"string","nullable":true},"story":{"type":"string","nullable":true}},"required":["user_id","name","age","gender","height_cm","weight_kg","bmi","smoker","alcohol_consumption","goal","story"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}},"put":{"tags":["Me"],"summary":"Update the user's health profile","description":"Partial update — only provided fields change. BMI is derived from height+weight. Anything omitted stays as-is; pass null to clear a field.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":80},"age":{"type":"integer","nullable":true,"minimum":0,"maximum":120},"gender":{"type":"string","nullable":true,"enum":["male","female"]},"height_cm":{"type":"number","nullable":true,"minimum":50,"maximum":260},"weight_kg":{"type":"number","nullable":true,"minimum":20,"maximum":400},"smoker":{"type":"string","nullable":true,"enum":["yes","no"]},"alcohol_consumption":{"type":"string","nullable":true,"enum":["never","occasional","regular"]},"conditions":{"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"maxItems":50},"medications":{"type":"array","items":{"type":"string","minLength":1,"maxLength":120},"maxItems":50},"goal":{"type":"string","maxLength":500},"story":{"type":"string","maxLength":1000}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"name":{"type":"string","nullable":true},"age":{"type":"number","nullable":true},"gender":{"type":"string","nullable":true},"height_cm":{"type":"number","nullable":true},"weight_kg":{"type":"number","nullable":true},"bmi":{"type":"number","nullable":true},"smoker":{"type":"string","nullable":true},"alcohol_consumption":{"type":"string","nullable":true},"conditions":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"duration_years":{"type":"number"}},"required":["name"]},"default":[]},"medications":{"type":"array","items":{"type":"string"},"default":[]},"goal":{"type":"string","nullable":true},"story":{"type":"string","nullable":true}},"required":["user_id","name","age","gender","height_cm","weight_kg","bmi","smoker","alcohol_consumption","goal","story"]}}}},"400":{"description":"Invalid input.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/sources":{"get":{"tags":["Sources"],"summary":"List connected wearables","description":"Returns every active wearable connection for the authenticated user.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"provider":{"type":"string","enum":["whoop","oura","garmin","fitbit","apple","google_fit","polar","withings","dexcom","freestyle_libre","other"]},"connected_at":{"type":"string","format":"date-time"},"last_sync_at":{"type":"string","nullable":true,"format":"date-time"},"status":{"type":"string","enum":["active","disconnected","error"]}},"required":["id","provider","connected_at","last_sync_at","status"]}}},"required":["data"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/sources/{id}":{"delete":{"tags":["Sources"],"summary":"Disconnect a wearable","description":"Marks the connection inactive. Terra access tokens are revoked on the Terra side via the connection lifecycle; ingested historical data is retained.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Disconnected."},"404":{"description":"No such source.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/labs/upload":{"post":{"tags":["Labs"],"summary":"Upload a bloodwork report","description":"Multipart upload of a lab PDF / image. The file is stored in R2, a `lab_uploads` row is recorded, and the binary is forwarded to Terra for OCR. Terra parses asynchronously (~30s); the resulting biomarkers land in your `/v1/data/sync` payload.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"nullable":true,"description":"PDF, PNG, or JPEG file (max 10MB)."}}}}}},"responses":{"200":{"description":"Submitted to Terra for parsing.","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"upload_id":{"type":"string"},"storage_key":{"type":"string"},"terra_status":{"type":"string"},"note":{"type":"string"}},"required":["ok","upload_id","storage_key","terra_status","note"]}}}},"400":{"description":"Malformed multipart or missing file.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"413":{"description":"File exceeds 10MB.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"415":{"description":"Unsupported file type.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"Terra rejected the upload.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/labs":{"get":{"tags":["Labs"],"summary":"List uploaded labs","description":"Returns the 20 most recent lab uploads for the user, summary form. `terra_status` flow: `pending` → `submitted` → `parsed` (or `failed:<reason>`).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"uploads":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"uploaded_at":{"type":"string"},"terra_status":{"type":"string"},"parsed_at":{"type":"string","nullable":true}},"required":["id","uploaded_at","terra_status","parsed_at"]}}},"required":["uploads"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/sources/terra/connect":{"post":{"tags":["Sources"],"summary":"Get a Terra widget URL","description":"Generates a Terra widget session URL that the user opens in a browser to OAuth their wearable. After they approve, Terra emits an `auth_success` webhook and subsequent data webhooks; `/v1/me` and `/v1/sources` will show the new connection.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string"},"redirect_url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Widget URL ready.","content":{"application/json":{"schema":{"type":"object","properties":{"widget_url":{"type":"string","format":"uri"},"session_id":{"type":"string"},"expires_in":{"type":"number"}},"required":["widget_url"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"Terra is unreachable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/connect":{"post":{"tags":["Sources"],"summary":"Get a Terra widget URL","description":"Generates a Terra widget session URL that the user opens in a browser to OAuth their wearable. After they approve, Terra emits an `auth_success` webhook and subsequent data webhooks; `/v1/me` and `/v1/sources` will show the new connection.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string"},"redirect_url":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Widget URL ready.","content":{"application/json":{"schema":{"type":"object","properties":{"widget_url":{"type":"string","format":"uri"},"session_id":{"type":"string"},"expires_in":{"type":"number"}},"required":["widget_url"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}},"502":{"description":"Terra is unreachable.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/data/sync":{"get":{"tags":["Data"],"summary":"Delta sync","description":"Returns every row updated since `since` (or `cursor`). Designed for offline-first clients: mirror the response into a local DB, then pass the response's `now` as the next request's `since`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"since","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"since":{"type":"string"},"now":{"type":"string"},"daily_summary":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"activities":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"sleep_sessions":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"biomarkers":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"biomarker_readings":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"counts":{"type":"object","properties":{"daily":{"type":"number"},"activities":{"type":"number"},"sleep":{"type":"number"},"biomarkers":{"type":"number"}},"required":["daily","activities","sleep","biomarkers"]},"backfill":{"type":"object","nullable":true,"properties":{"active":{"type":"boolean"},"percent":{"type":"number"},"received":{"type":"number"},"expected":{"type":"number"}},"required":["active","percent","received","expected"]}},"required":["user_id","since","now","daily_summary","activities","sleep_sessions","biomarkers","biomarker_readings","counts","backfill"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/sync":{"get":{"tags":["Data"],"summary":"Delta sync","description":"Returns every row updated since `since` (or `cursor`). Designed for offline-first clients: mirror the response into a local DB, then pass the response's `now` as the next request's `since`.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"since","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"since":{"type":"string"},"now":{"type":"string"},"daily_summary":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"activities":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"sleep_sessions":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"biomarkers":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"biomarker_readings":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"counts":{"type":"object","properties":{"daily":{"type":"number"},"activities":{"type":"number"},"sleep":{"type":"number"},"biomarkers":{"type":"number"}},"required":["daily","activities","sleep","biomarkers"]},"backfill":{"type":"object","nullable":true,"properties":{"active":{"type":"boolean"},"percent":{"type":"number"},"received":{"type":"number"},"expected":{"type":"number"}},"required":["active","percent","received","expected"]}},"required":["user_id","since","now","daily_summary","activities","sleep_sessions","biomarkers","biomarker_readings","counts","backfill"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/v1/insight":{"get":{"tags":["Insight"],"summary":"Today's precomputed daily insight","description":"Amy's single most non-obvious, grounded cross-domain insight for today, generated by one Opus call over a deterministic candidate engine and cached per local day. Pass ?force=1 to regenerate.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":false,"name":"force","in":"query"}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"user_id":{"type":"string"},"date":{"type":"string"},"headline":{"type":"string"},"detail":{"type":"string"},"basis":{"type":"array","items":{"type":"string"},"default":[]},"domains":{"type":"array","items":{"type":"string"},"default":[]},"kind":{"type":"string","default":"none"},"confidence":{"type":"string","default":"medium"},"confounder":{"type":"string","nullable":true,"default":null},"lever":{"type":"string","nullable":true,"default":null},"ask_prompt":{"type":"string","default":""},"generated_at":{"type":"string"}},"required":["user_id","date","headline","detail","generated_at"]}}}},"401":{"description":"Missing or invalid bearer.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["missing_authorization","invalid_token","forbidden","invalid_request","invalid_field","unprocessable","not_found","turn_not_found","lab_not_found","source_not_found","memory_not_found","already_exists","idempotency_key_mismatch","rate_limit_exceeded","concurrency_limit_exceeded","internal_error","upstream_unavailable","webhook_signature_invalid"]},"message":{"type":"string"},"request_id":{"type":"string"},"docs_url":{"type":"string","format":"uri"},"details":{"nullable":true}},"required":["code","message","request_id"]}},"required":["error"]}}}}}}},"/healthz":{"get":{"tags":["Meta"],"summary":"Liveness check","description":"Always 200 when the Worker is up. Used by monitoring.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"env":{"type":"string"}},"required":["ok","env"]}}}}}}}}}