{"openapi":"3.1.0","info":{"title":"Wave API","version":"1.0.0","description":"API for accessing Wave AI session data, transcripts, and managing webhooks. Build AI integrations, CRM syncs, analytics dashboards, and productivity tools.","contact":{"name":"Wave Support","url":"https://wave.co"}},"servers":[{"url":"https://api.wave.co","description":"Production"}],"tags":[{"name":"Sharing","description":"Share sessions and manage access with sharing:manage. Per-invite scope, Teams, and share events are not supported."},{"name":"Shared sessions","description":"Read sessions shared with you. Read-only; search does not cover shared sessions."},{"name":"Sessions","description":"List, search, update, and delete sessions. PATCH supports structured action items with optimistic concurrency."},{"name":"Folders","description":"Create, rename, recolour, pin, reorder and delete folders, and manage non-exclusive session membership. Use with `GET /v1/sessions?folder=…` for filtered listing."},{"name":"Transcripts","description":"Access session transcripts with speaker segments"},{"name":"Media","description":"Get signed URLs for audio and video files"},{"name":"Account","description":"User profile and subscription info"},{"name":"Events","description":"Per-token cursor feed. Poll and ack instead of running a webhook receiver; same event shapes."},{"name":"Webhooks","description":"Register and manage webhook endpoints"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Wave API token (wave_api_...)"}},"schemas":{"APIError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]}},"required":["error"],"example":{"error":{"code":"not_found","message":"Session not found"}}},"WebhookEventPayload":{"type":"object","properties":{"id":{"type":"string"},"event":{"$ref":"#/components/schemas/WebhookEventType"},"created_at":{"type":"string"},"data":{"type":"object","properties":{"session":{"$ref":"#/components/schemas/SessionDetail"}},"required":["session"]}},"required":["id","event","created_at","data"],"example":{"id":"evt_01HX4R7MT8PQZ6VCN9ABYF2KJM","event":"session.completed","created_at":"2025-04-21T17:14:08.120Z","data":{"session":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","language":"en","summary":"## Overview\nQuarterly roadmap review…","notes":null,"tags":["work","roadmap"],"favorite":false}}}},"WebhookEventType":{"type":"string","enum":["session.completed","session.updated","session.deleted","session.action_items.updated"]},"SessionDetail":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"timestamp":{"type":["string","null"]},"duration_seconds":{"type":"number"},"type":{"type":"string"},"platform":{"type":["string","null"]},"language":{"type":["string","null"]},"summary":{"type":["string","null"]},"notes":{"type":["string","null"]},"tags":{"type":"array","items":{"type":"string"}},"favorite":{"type":"boolean"},"folder_ids":{"type":"array","items":{"type":"string"}},"action_items":{"type":"array","items":{"$ref":"#/components/schemas/ActionItem"}},"action_items_version":{"type":"number"},"audio_deleted_at":{"type":["string","null"],"format":"date-time","description":"When the session's audio recording was deleted (by the user, their retention policy, or an admin), or null. The transcript and summary are kept; /v1/sessions/{id}/media returns null URLs."},"phone":{"$ref":"#/components/schemas/PhoneMetadata"}},"required":["id","title","timestamp","duration_seconds","type","platform","language","summary","notes","audio_deleted_at"],"example":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","language":"en","summary":"## Overview\nQuarterly roadmap review with the retail-media pod.\n\n## Key points\n- Shifting Q3 priorities to Instacart rollout\n- Blocked on legal review for sponsored SKUs\n\n## Action items\n- [ ] JR: send legal the draft spec (Fri)\n- [ ] Sam: mock up the new placement UI","notes":"Pre-read doc in Notion; follow up on legal timeline.","tags":["work","roadmap"],"favorite":false,"audio_deleted_at":null}},"ActionItem":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"completed":{"type":"boolean"},"source":{"type":"string","enum":["agent","user"]},"assignee":{"type":["string","null"]},"due_date":{"type":["string","null"],"format":"date","description":"Due date as an ISO calendar date (YYYY-MM-DD), or null. Natural-language input is normalized to this form on write."},"source_start":{"type":["number","null"],"description":"Transcript offset in seconds where the item was committed to. Set by Wave when extracting items; preserved across edits."},"user_edited_at":{"type":["number","null"],"description":"Epoch milliseconds of the last time a client changed this item's text or due_date. null when never edited since extraction."},"created_at":{"type":"number"},"updated_at":{"type":"number"}},"required":["id","text","completed","source","created_at","updated_at"],"example":{"id":"ai_01HX4R7MT8PQZ6VCN9ABYF2KJM","text":"Send legal the draft spec by Friday","completed":false,"source":"agent","assignee":"JR","due_date":"2025-04-25","user_edited_at":null,"created_at":1745258048120,"updated_at":1745258048120}},"PhoneMetadata":{"type":"object","properties":{"direction":{"type":["string","null"],"enum":["inbound","outbound",null]},"to_number":{"type":["string","null"]},"from_number":{"type":["string","null"]},"status":{"type":["string","null"],"enum":["ringing","in_progress","completed","missed","failed",null]},"ongoing":{"type":"boolean"},"provider":{"type":["string","null"]},"contact_name":{"type":["string","null"]}},"required":["direction","to_number","from_number","status","ongoing","provider","contact_name"],"description":"Call metadata, present only on sessions of type \"phone\". For inbound (bridge) calls the other party is unknown: to_number is the user’s verified caller id and from_number is null.","example":{"direction":"outbound","to_number":"+15551234567","from_number":"+15559876543","status":"completed","ongoing":false,"provider":"telnyx","contact_name":"Acme Co."}},"EventEnvelope":{"type":"object","properties":{"id":{"type":"string"},"seq":{"type":"number"},"event":{"$ref":"#/components/schemas/WebhookEventType"},"created_at":{"type":"string"},"data":{"type":"object","properties":{"session":{"$ref":"#/components/schemas/SessionDetail"}},"required":["session"]}},"required":["id","seq","event","created_at","data"],"example":{"id":"evt_01HX4R7MT8PQZ6VCN9ABYF2KJM","seq":4281,"event":"session.completed","created_at":"2025-04-21T17:14:08.120Z","data":{"session":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","language":"en","summary":"## Overview\nQuarterly roadmap review…","notes":null,"tags":["work","roadmap"],"favorite":false}}}},"SessionListResponse":{"type":"object","properties":{"sessions":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/SessionListItem"},{"$ref":"#/components/schemas/SharedSessionListRow"}]},"description":"Own rows (`SessionListItem`). With `?include=shared`, the first page also carries `SharedSessionListRow`s (`access: \"shared\"`) after the own rows; own rows then carry `access: \"owner\"`. Discriminate on `access`."},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"},"shared_error":{"type":"string","enum":["sharing_unavailable"],"description":"Only with `?include=shared`: the shared rows could not be loaded, so `sessions` holds own rows only. The list is incomplete; retry or call GET /v1/shared-sessions."}},"required":["sessions","next_cursor","has_more"],"example":{"sessions":[{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","audio_deleted_at":null},{"id":"sess_01HX3P8YVJ9WX1MKBQ2NTD5VGH","title":"Customer call — Acme Co.","timestamp":"2025-04-17T20:30:00.000Z","duration_seconds":2455,"type":"meeting","platform":"google_meet","audio_deleted_at":null}],"next_cursor":"2025-04-17T20:30:00.000Z","has_more":true}},"SessionListItem":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"timestamp":{"type":["string","null"]},"duration_seconds":{"type":"number"},"type":{"type":"string"},"platform":{"type":["string","null"]},"audio_deleted_at":{"type":["string","null"],"format":"date-time","description":"When the session's audio recording was deleted (by the user, their retention policy, or an admin), or null. The transcript and summary are kept; /v1/sessions/{id}/media returns null URLs."},"phone":{"$ref":"#/components/schemas/PhoneMetadata"},"access":{"type":"string","enum":["owner"],"description":"`\"owner\"`; present only with `?include=shared`."}},"required":["id","title","timestamp","duration_seconds","type","platform","audio_deleted_at"],"example":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","audio_deleted_at":null}},"SharedSessionListRow":{"allOf":[{"$ref":"#/components/schemas/SharedSessionListItem"},{"type":"object","properties":{"access":{"type":"string","enum":["shared"]}},"required":["access"]}]},"ShareScope":{"type":"object","properties":{"summary":{"type":"boolean"},"transcript":{"type":"boolean"},"audio":{"type":"boolean"},"action_items":{"type":"boolean"}},"required":["summary","transcript","audio","action_items"]},"SharedSessionListItem":{"type":"object","properties":{"id":{"type":"string"},"owner":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]}},"required":["id","name"]},"title":{"type":"string"},"shared_at":{"type":["string","null"]},"scope":{"$ref":"#/components/schemas/ShareScope"},"session_url":{"type":"string"}},"required":["id","owner","title","shared_at","scope","session_url"]},"FolderListResponse":{"type":"object","properties":{"folders":{"type":"array","items":{"$ref":"#/components/schemas/Folder"}}},"required":["folders"],"example":{"folders":[{"id":"fld_01HX4R7MT8PQZ6VCN9ABYF2KJM","name":"work","color":"#6D28D9","session_count":82,"created_at":"2026-09-01T14:02:11.000Z","updated_at":"2026-09-05T09:41:37.000Z","pinned":true,"sort_order":"newest","order":0,"last_opened_at":"2026-09-06T08:15:02.000Z"},{"id":"fld_01HX5S8NV9QR0XDJ2KBC7ZG3HT","name":"personal","color":"#F59E0B","session_count":14,"created_at":"2026-08-12T18:30:00.000Z","updated_at":"2026-08-12T18:30:00.000Z"}]}},"Folder":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"color":{"type":["string","null"]},"session_count":{"type":"number"},"created_at":{"type":"string","description":"ISO 8601. Absent on folders created before timestamps were introduced."},"updated_at":{"type":"string","description":"ISO 8601. Bumped on rename, recolour, pin/reorder/sort changes, and membership changes. Absent on folders never mutated since timestamps were introduced."},"pinned":{"type":"boolean","description":"Pinned folders sort first everywhere. Absent means not pinned."},"sort_order":{"$ref":"#/components/schemas/FolderSortOrder"},"order":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Manual position (integer from 0 to 2^53 - 1). Folders with `order` sort ascending before folders without it. Absent means no manual position."},"last_opened_at":{"type":"string","description":"ISO 8601. When the folder's contents were last viewed in a Wave client. Absent if never recorded."}},"required":["id","name","color","session_count"],"example":{"id":"fld_01HX4R7MT8PQZ6VCN9ABYF2KJM","name":"work","color":"#6D28D9","session_count":82,"created_at":"2026-09-01T14:02:11.000Z","updated_at":"2026-09-05T09:41:37.000Z","pinned":true,"sort_order":"newest","order":0,"last_opened_at":"2026-09-06T08:15:02.000Z"}},"FolderSortOrder":{"type":"string","enum":["newest","oldest","title"],"description":"Remembered sort for the sessions inside a folder: `newest` (session timestamp descending; the default when absent), `oldest`, or `title`."},"CreateFolderRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"pattern":"\\S","description":"Folder name. Trimmed; 1–100 characters, not blank."},"color":{"type":["string","null"],"pattern":"^#[0-9a-fA-F]{6}$","description":"Hex colour like `#6D28D9`, or null for no colour."}},"required":["name"],"example":{"name":"client-calls","color":"#6D28D9"}},"PatchFolderRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100,"pattern":"\\S","description":"New folder name. Trimmed; 1–100 characters, not blank."},"color":{"type":["string","null"],"pattern":"^#[0-9a-fA-F]{6}$","description":"Hex colour like `#4D5EF6`, or null to clear the colour."},"pinned":{"type":"boolean","description":"Pin (true) or unpin (false) the folder. Pinned folders sort first everywhere."},"sort_order":{"$ref":"#/components/schemas/FolderSortOrder"},"order":{"type":"integer","minimum":0,"maximum":9007199254740991,"description":"Manual position, integer from 0 to 2^53 - 1. Folders with `order` sort ascending before folders without it."}},"description":"At least one of `name` / `color` / `pinned` / `sort_order` / `order` is required (see `anyOf`). Omitted fields are left unchanged.","anyOf":[{"required":["name"]},{"required":["color"]},{"required":["pinned"]},{"required":["sort_order"]},{"required":["order"]}],"example":{"name":"Customer research","color":"#4D5EF6","pinned":true,"sort_order":"oldest","order":2}},"FolderMembershipResponse":{"type":"object","properties":{"session_id":{"type":"string"},"folder_id":{"type":"string"},"folder_ids":{"type":"array","items":{"type":"string"}}},"required":["session_id","folder_id","folder_ids"],"example":{"session_id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","folder_id":"fld_01HX4R7MT8PQZ6VCN9ABYF2KJM","folder_ids":["fld_01HX4R7MT8PQZ6VCN9ABYF2KJM","fld_01HX5S8NV9QR0XDJ2KBC7ZG3HT"]}},"PatchSessionResponse":{"type":"object","properties":{"id":{"type":"string"},"updated_fields":{"type":"array","items":{"type":"string"}},"updated_at":{"type":"string"},"action_items_version":{"type":"number"}},"required":["id","updated_fields","updated_at"],"example":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","updated_fields":["tags","favorite","action_items"],"updated_at":"2025-04-21T17:14:08.120Z","action_items_version":3}},"PatchSessionRequest":{"type":"object","properties":{"title":{"type":"string","maxLength":500},"notes":{"type":"string","maxLength":50000},"tags":{"type":"array","items":{"type":"string","maxLength":100},"maxItems":20},"favorite":{"type":"boolean"},"action_items":{"type":"array","items":{"$ref":"#/components/schemas/ActionItemInput"},"maxItems":200}},"example":{"tags":["work","roadmap"],"favorite":true,"action_items":[{"text":"Send legal the draft spec by Friday","assignee":"JR","due_date":"2025-04-25"},{"text":"Mock up the new placement UI","assignee":"Sam"}]}},"ActionItemInput":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string","minLength":1,"maxLength":2000},"completed":{"type":"boolean"},"source":{"type":"string","enum":["agent","user"]},"assignee":{"type":["string","null"],"maxLength":200},"due_date":{"type":["string","null"],"maxLength":100,"description":"Due date. ISO YYYY-MM-DD preferred; natural language such as \"Friday\", \"next Tuesday\" or \"April 25\" is accepted and normalized to ISO relative to today. null or \"\" clears the date; omit the field to keep the current one. Unparseable values are rejected with 400."}},"required":["text"],"example":{"text":"Send legal the draft spec by Friday","assignee":"JR","due_date":"2025-04-25"}},"ActionItemsResponse":{"type":"object","properties":{"session_id":{"type":"string"},"action_items":{"type":"array","items":{"$ref":"#/components/schemas/ActionItem"}},"version":{"type":"number"},"updated_at":{"type":["string","null"]}},"required":["session_id","action_items","version","updated_at"],"example":{"session_id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","action_items":[{"id":"ai_01HX4R7MT8PQZ6VCN9ABYF2KJM","text":"Send legal the draft spec by Friday","completed":false,"source":"agent","assignee":"JR","due_date":"2025-04-25","user_edited_at":null,"created_at":1745258048120,"updated_at":1745258048120}],"version":3,"updated_at":"2025-04-21T17:14:08.120Z"}},"DeleteSessionResponse":{"type":"object","properties":{"deleted":{"type":"boolean"},"id":{"type":"string"}},"required":["deleted","id"],"example":{"deleted":true,"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM"}},"TranscriptResponse":{"type":"object","properties":{"id":{"type":"string"},"transcript":{"type":"string"},"segments":{"type":"array","items":{"$ref":"#/components/schemas/Segment"}}},"required":["id","transcript"],"example":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","transcript":"Josh: Alright, let’s kick off the roadmap review.\nSam: Sure — I sent the draft last night.\nJosh: Great, want to start with retail media?","segments":[{"speaker":"Josh","start":12.48,"end":15.92,"text":"Alright, let’s kick off the roadmap review."},{"speaker":"Sam","start":16.04,"end":18.31,"text":"Sure — I sent the draft last night."},{"speaker":"Josh","start":18.5,"end":21.02,"text":"Great, want to start with retail media?"}]}},"Segment":{"type":"object","properties":{"speaker":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"},"text":{"type":"string"}},"required":["speaker","start","end","text"],"example":{"speaker":"Josh","start":12.48,"end":15.92,"text":"Alright, let’s kick off the roadmap review."}},"MediaResponse":{"type":"object","properties":{"id":{"type":"string"},"audio_url":{"type":["string","null"]},"video_url":{"type":["string","null"]},"expires_at":{"type":"string"},"audio_deleted_at":{"type":["string","null"],"format":"date-time","description":"When the session's audio recording was deleted (by the user, their retention policy, or an admin), or null. The transcript and summary are kept; /v1/sessions/{id}/media returns null URLs."}},"required":["id","audio_url","video_url","expires_at","audio_deleted_at"],"example":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","audio_url":"https://storage.googleapis.com/table-talk-b87f8.appspot.com/Users/uid_.../audio.m4a?X-Goog-Signature=…","video_url":null,"expires_at":"2025-04-21T18:14:08.000Z","audio_deleted_at":null}},"SearchResponse":{"type":"object","properties":{"query":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchResult"}},"total":{"type":"number"}},"required":["query","results","total"],"example":{"query":"retail media strategy","results":[{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","type":"meeting","similarity":0.87,"snippet":"…we want to lead with retail media strategy in Q3, starting with the Instacart rollout…"}],"total":1}},"SearchResult":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"timestamp":{"type":["string","null"]},"type":{"type":"string"},"similarity":{"type":"number"},"snippet":{"type":"string"},"phone":{"$ref":"#/components/schemas/PhoneMetadata"}},"required":["id","title","timestamp","type","snippet"],"example":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","type":"meeting","similarity":0.87,"snippet":"…we want to lead with retail media strategy in Q3, starting with the Instacart rollout…"}},"SearchRequest":{"type":"object","properties":{"query":{"type":"string","minLength":1},"limit":{"type":"integer","minimum":1,"maximum":50},"tags":{"type":"array","items":{"type":"string"},"maxItems":20},"tag_mode":{"type":"string","enum":["any","all"]}},"required":["query"],"example":{"query":"retail media strategy","limit":10,"tags":["work"],"tag_mode":"any"}},"StatsResponse":{"type":"object","properties":{"total_sessions":{"type":"number"},"total_duration_seconds":{"type":"number"},"average_duration_seconds":{"type":"number"},"sessions_by_type":{"type":"object","additionalProperties":{"type":"number"}},"sessions_by_platform":{"type":"object","additionalProperties":{"type":"number"}},"period":{"type":"object","properties":{"since":{"type":"string"},"until":{"type":"string"}},"required":["since","until"]}},"required":["total_sessions","total_duration_seconds","average_duration_seconds","sessions_by_type","sessions_by_platform","period"],"example":{"total_sessions":57,"total_duration_seconds":89432,"average_duration_seconds":1569,"sessions_by_type":{"meeting":38,"phone":11,"recording":8},"sessions_by_platform":{"zoom":22,"google_meet":12,"phone":11,"desktop":8,"none":4},"period":{"since":"2025-03-22T00:00:00.000Z","until":"2025-04-21T00:00:00.000Z"}}},"BulkExportResponse":{"type":"object","properties":{"sessions":{"type":"array","items":{"$ref":"#/components/schemas/BulkExportSession"}},"errors":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"error":{"type":"string"}},"required":["id","error"]}}},"required":["sessions","errors"],"example":{"sessions":[{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","language":"en","summary":"## Overview\nQuarterly roadmap review…","transcript":"Josh: Alright, let’s kick off the roadmap review.…"}],"errors":[{"id":"sess_does_not_exist","error":"not_found"}]}},"BulkExportSession":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"timestamp":{"type":["string","null"]},"duration_seconds":{"type":"number"},"type":{"type":"string"},"platform":{"type":["string","null"]},"language":{"type":["string","null"]},"summary":{"type":["string","null"]},"transcript":{"type":["string","null"]},"phone":{"$ref":"#/components/schemas/PhoneMetadata"}},"required":["id","title","timestamp","duration_seconds","type","platform","language"],"example":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","language":"en","summary":"## Overview\nQuarterly roadmap review…","transcript":"Josh: Alright, let’s kick off the roadmap review.\nSam: Sure — I sent the draft last night.…"}},"BulkExportRequest":{"type":"object","properties":{"session_ids":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":50},"include_transcript":{"type":"boolean"},"include_summary":{"type":"boolean"}},"required":["session_ids"],"example":{"session_ids":["sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","sess_01HX3P8YVJ9WX1MKBQ2NTD5VGH"],"include_transcript":true,"include_summary":true}},"AccountResponse":{"type":"object","properties":{"user_id":{"type":"string"},"subscription_active":{"type":"boolean"},"session_count":{"type":"number"}},"required":["user_id","subscription_active","session_count"],"example":{"user_id":"uid_V7hTqM3aRe5xJ8pL2nKbS6wY","subscription_active":true,"session_count":421}},"EventsListResponse":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/EventEnvelope"}},"next_cursor":{"type":["number","null"]},"has_more":{"type":"boolean"}},"required":["events","next_cursor","has_more"],"example":{"events":[{"id":"evt_01HX4R7MT8PQZ6VCN9ABYF2KJM","seq":4281,"event":"session.completed","created_at":"2025-04-21T17:14:08.120Z","data":{"session":{"id":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM","title":"Weekly product sync","timestamp":"2025-04-18T16:00:00.000Z","duration_seconds":1812,"type":"meeting","platform":"zoom","language":"en","summary":"## Overview\n…","notes":null,"tags":["work"],"favorite":false}}}],"next_cursor":4281,"has_more":false}},"AckEventsResponse":{"type":"object","properties":{"acknowledged_cursor":{"type":"number"}},"required":["acknowledged_cursor"],"example":{"acknowledged_cursor":4281}},"AckEventsRequest":{"type":"object","properties":{"cursor":{"type":"integer","minimum":0}},"required":["cursor"],"example":{"cursor":4281}},"WebhookListResponse":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookResponse"}}},"required":["webhooks"],"example":{"webhooks":[{"id":"wh_01HX4R7MT8PQZ6VCN9ABYF2KJM","url":"https://example.com/wave/webhook","events":["session.completed"],"active":true,"failure_count":0,"last_delivery_at":"2025-04-21T15:02:11.000Z","last_delivery_status":200,"created_at":"2025-04-20T18:32:14.000Z","updated_at":"2025-04-21T15:02:11.000Z"}]}},"WebhookResponse":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"}},"active":{"type":"boolean"},"failure_count":{"type":"number"},"last_delivery_at":{"type":["string","null"]},"last_delivery_status":{"type":["number","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"secret":{"type":"string"}},"required":["id","url","events","active","failure_count","last_delivery_at","last_delivery_status","created_at","updated_at"],"example":{"id":"wh_01HX4R7MT8PQZ6VCN9ABYF2KJM","url":"https://example.com/wave/webhook","events":["session.completed","session.updated"],"active":true,"failure_count":0,"last_delivery_at":"2025-04-21T15:02:11.000Z","last_delivery_status":200,"created_at":"2025-04-20T18:32:14.000Z","updated_at":"2025-04-21T15:02:11.000Z","secret":"whsec_7j3LxGf9qA2pRn5bXcV1MdKt"}},"CreateWebhookRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"},"minItems":1}},"required":["url","events"],"example":{"url":"https://example.com/wave/webhook","events":["session.completed","session.updated"]}},"PatchWebhookRequest":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEventType"},"minItems":1},"active":{"type":"boolean"}},"example":{"events":["session.completed","session.updated","session.deleted"],"active":true}},"WebhookTestResponse":{"type":"object","properties":{"success":{"type":"boolean"},"event":{"type":"string"},"webhook_id":{"type":"string"},"delivered_at":{"type":"string"}},"required":["success","event","webhook_id","delivered_at"],"example":{"success":true,"event":"session.completed","webhook_id":"wh_01HX4R7MT8PQZ6VCN9ABYF2KJM","delivered_at":"2025-04-21T17:14:08.120Z"}},"SharedSessionListResponse":{"type":"object","properties":{"sessions":{"type":"array","items":{"$ref":"#/components/schemas/SharedSessionListItem"}},"next_cursor":{"type":["string","null"]},"has_more":{"type":"boolean"}},"required":["sessions","next_cursor","has_more"]},"SharedSessionDetail":{"allOf":[{"$ref":"#/components/schemas/SharedSessionListItem"},{"type":"object","properties":{"timestamp":{"type":["string","null"]},"duration_seconds":{"type":"number"},"type":{"type":"string"},"platform":{"type":["string","null"]},"status":{"type":["string","null"]},"in_process":{"type":"boolean"},"summary":{"type":["string","null"]},"action_items":{"type":"array","items":{"$ref":"#/components/schemas/SharedActionItem"}}},"required":["timestamp","duration_seconds","type","platform","status","in_process"]}]},"SharedActionItem":{"type":"object","properties":{"id":{"type":"string"},"text":{"type":"string"},"completed":{"type":"boolean"},"assignee":{"type":["string","null"]},"due_date":{"type":["string","null"],"format":"date","description":"Due date as an ISO calendar date (YYYY-MM-DD), or null. Natural-language input is normalized to this form on write."},"source_start":{"type":["number","null"],"description":"Transcript offset in seconds where the item was committed to. Set by Wave when extracting items; preserved across edits."}},"required":["id","text","completed"]},"SharedTranscriptResponse":{"type":"object","properties":{"id":{"type":"string"},"transcript":{"type":"string"},"segments":{"type":"array","items":{"type":"object","properties":{"speaker":{"type":"string"},"start":{"type":"number"},"end":{"type":"number"},"text":{"type":"string"}},"required":["text"]}}},"required":["id","transcript"]},"SharedActionItemsResponse":{"type":"object","properties":{"session_id":{"type":"string"},"action_items":{"type":"array","items":{"$ref":"#/components/schemas/SharedActionItem"}},"version":{"type":"number","enum":[0],"description":"Read-only placeholder; the callable does not expose edit versions."},"updated_at":{"type":"null"}},"required":["session_id","action_items","version","updated_at"]},"SharedMediaResponse":{"type":"object","properties":{"kind":{"type":"string","enum":["audio","video"]},"url":{"type":"string"},"expires_at":{"type":["string","null"]},"external":{"type":"boolean"}},"required":["kind","url","expires_at","external"]},"SessionSharingResponse":{"type":"object","properties":{"people":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"email":{"type":["string","null"]},"shared_at":{"type":["string","null"]},"sources":{"type":"array","items":{"type":"string"}}},"required":["id","name","email","shared_at","sources"]}},"pending_invites":{"type":"array","items":{"type":"object","properties":{"email":{"type":["string","null"]},"sent_at":{"type":["string","null"]},"last_sent_at":{"type":["string","null"]},"send_count":{"type":"number"},"invite_id":{"type":["string","null"]}},"required":["email","sent_at","last_sent_at","send_count","invite_id"]}},"link":{"type":"object","properties":{"url":{"type":"null"}},"required":["url"]}},"required":["people","pending_invites","link"]},"ShareLinkResponse":{"type":"object","properties":{"url":{"type":"string"},"expires_at":{"type":"string"}},"required":["url","expires_at"]},"ResetShareLinkResponse":{"allOf":[{"$ref":"#/components/schemas/ShareLinkResponse"},{"type":"object","properties":{"removed":{"type":"number"}},"required":["removed"]}]},"ResetShareLinkRequest":{"type":"object","properties":{"remove_everyone":{"type":"boolean"}},"additionalProperties":false},"SendShareInvitesResponse":{"type":"object","properties":{"sent":{"type":"array","items":{"type":"string"}},"skipped":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"reason":{"type":"string"}},"required":["email","reason"]}},"expires_at":{"type":["string","null"]}},"required":["sent","skipped","expires_at"]},"SendShareInvitesRequest":{"type":"object","properties":{"emails":{"type":"array","items":{"type":"string","minLength":1,"maxLength":320},"minItems":1,"maxItems":10},"message":{"type":"string","maxLength":500}},"required":["emails"],"additionalProperties":false},"CancelShareInviteResponse":{"type":"object","properties":{"cancelled":{"type":"boolean"}},"required":["cancelled"]},"CancelShareInviteRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"invite_id":{"type":"string","minLength":1,"maxLength":1500}},"required":["email"],"additionalProperties":false}},"parameters":{}},"paths":{"/v1/sessions":{"get":{"summary":"List sessions","description":"List sessions with cursor-based pagination. Only returns completed sessions (with summaries). Response shape is stable; every session includes `id`, `title`, `timestamp`, `duration_seconds`, `type`, and `platform`.","tags":["Sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Max results (default 20, max 100)","example":"20"},"required":false,"description":"Max results (default 20, max 100)","name":"limit","in":"query"},{"schema":{"type":"string","description":"ISO 8601 date for pagination (sessions older than this)","example":"2025-04-17T20:30:00.000Z"},"required":false,"description":"ISO 8601 date for pagination (sessions older than this)","name":"cursor","in":"query"},{"schema":{"type":"string","description":"ISO 8601 date (sessions newer than this)","example":"2025-04-01T00:00:00.000Z"},"required":false,"description":"ISO 8601 date (sessions newer than this)","name":"since","in":"query"},{"schema":{"type":"string","description":"Filter by session type (meeting, recording, phone, desktop, import, youtube, podcast)","example":"meeting"},"required":false,"description":"Filter by session type (meeting, recording, phone, desktop, import, youtube, podcast)","name":"type","in":"query"},{"schema":{"type":"string","description":"Filter by folder id or case-insensitive name. Restricts results to sessions in that folder. Ideal for default-deny work/personal separation on a single account.","example":"work"},"required":false,"description":"Filter by folder id or case-insensitive name. Restricts results to sessions in that folder. Ideal for default-deny work/personal separation on a single account.","name":"folder","in":"query"},{"schema":{"type":"string","description":"Filter by tag (exact, case-sensitive). Repeatable (`?tag=a&tag=b`) or comma-separated (`?tag=a,b`). Pair with `tag_mode=all` to require every tag.","example":"roadmap"},"required":false,"description":"Filter by tag (exact, case-sensitive). Repeatable (`?tag=a&tag=b`) or comma-separated (`?tag=a,b`). Pair with `tag_mode=all` to require every tag.","name":"tag","in":"query"},{"schema":{"type":"string","description":"`any` (default) returns sessions matching at least one of the listed tags; `all` requires every listed tag.","example":"any"},"required":false,"description":"`any` (default) returns sessions matching at least one of the listed tags; `all` requires every listed tag.","name":"tag_mode","in":"query"},{"schema":{"type":"string","description":"`shared` appends the sessions other Wave users shared with you to the first page (no `cursor`) as read-only `SharedSessionListRow`s (`access: \"shared\"`; no `timestamp`/`duration_seconds`/`type`); your own rows then carry `access: \"owner\"`. Shared rows ignore `type`, `folder`, `tag` and `since`. If shared rows cannot be loaded the response carries `shared_error: \"sharing_unavailable\"` with own rows only. Default: own sessions only.","example":"shared"},"required":false,"description":"`shared` appends the sessions other Wave users shared with you to the first page (no `cursor`) as read-only `SharedSessionListRow`s (`access: \"shared\"`; no `timestamp`/`duration_seconds`/`type`); your own rows then carry `access: \"owner\"`. Shared rows ignore `type`, `folder`, `tag` and `since`. If shared rows cannot be loaded the response carries `shared_error: \"sharing_unavailable\"` with own rows only. Default: own sessions only.","name":"include","in":"query"}],"responses":{"200":{"description":"Session list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionListResponse"}}}},"400":{"description":"Invalid request (bad tag_mode, etc.)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"Folder not found (only when `folder` param is passed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/folders":{"get":{"summary":"List folders","description":"List all folders for the authenticated user. Each folder carries the sessions the user has organized into it in the Wave app. Folders are non-exclusive — a session can belong to many folders at once. Use the folder `id` or `name` with `GET /v1/sessions?folder=…` to restrict a session list to one folder. Requires the `folders:read` scope; `sessions:read` is also accepted for backward compatibility. `created_at` / `updated_at` and the preferences `pinned` / `sort_order` / `order` / `last_opened_at` are included when present; absence means the default (not pinned, newest first, no manual position, never opened). Folders are returned in display order: pinned first, then `order` ascending (folders with an `order` before those without), then name.","tags":["Folders"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Folder list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"post":{"summary":"Create folder","description":"Create a new folder. Name collisions (case-insensitive) return the existing folder — the endpoint is safe to retry. `name` is trimmed and must be 1–100 characters; `color` is a hex string like `#6D28D9` or null. The folder is stamped with `created_at` / `updated_at`. Requires the `folders:write` scope.","tags":["Folders"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFolderRequest"}}}},"responses":{"201":{"description":"Folder created (or returned if it already existed)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/folders/{id}":{"get":{"summary":"Get folder","description":"Fetch one folder by id, including its session count, `created_at` / `updated_at`, and the preferences `pinned` / `sort_order` / `order` / `last_opened_at` when present. Requires the `folders:read` scope; `sessions:read` is also accepted.","tags":["Folders"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID","example":"fld_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Folder ID","name":"id","in":"path"}],"responses":{"200":{"description":"Folder","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folder"}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"Folder not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"patch":{"summary":"Update folder","description":"Rename, recolour, pin, reorder, or change the session sort of a folder. At least one of `name` (trimmed, 1–100 characters), `color` (hex like `#4D5EF6`, or null to clear), `pinned` (boolean), `sort_order` (`newest` | `oldest` | `title`), or `order` (integer >= 0, manual position) is required; omitted fields are unchanged. Bumps `updated_at`. Membership is managed separately via the session-folder endpoints. Requires the `folders:write` scope.","tags":["Folders"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID","example":"fld_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Folder ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchFolderRequest"}}}},"responses":{"200":{"description":"Updated folder","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Folder"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"Folder not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"delete":{"summary":"Delete folder","description":"Delete a folder. Only the folder is removed — the sessions in it are never deleted, and their folder membership is cleaned up automatically. Requires the `folders:write` scope.","tags":["Folders"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Folder ID","example":"fld_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Folder ID","name":"id","in":"path"}],"responses":{"204":{"description":"Folder deleted (no body)"},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"Folder not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/folders/{folderId}":{"post":{"summary":"Add session to folder","description":"Link a session to a folder. Folders are non-exclusive — calling this for a session already in the folder is a no-op, and a session can sit in any number of folders simultaneously. Bumps the folder's `updated_at`. Requires the `folders:write` scope.","tags":["Folders"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID"},"required":true,"description":"Session ID","name":"id","in":"path"},{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Session added to folder","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderMembershipResponse"}}}},"404":{"description":"Session or folder not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"delete":{"summary":"Remove session from folder","description":"Unlink a session from a folder. The session itself is not deleted. Bumps the folder's `updated_at`. Requires the `folders:write` scope.","tags":["Folders"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID"},"required":true,"description":"Session ID","name":"id","in":"path"},{"schema":{"type":"string","description":"Folder ID"},"required":true,"description":"Folder ID","name":"folderId","in":"path"}],"responses":{"200":{"description":"Session removed from folder","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FolderMembershipResponse"}}}},"404":{"description":"Folder not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}":{"get":{"summary":"Get session details","description":"Get detailed information about a specific session, including summary (structured markdown), notes, tags, and favorite flag. Transcript is fetched separately via `/v1/sessions/{id}/transcript`.","tags":["Sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID","example":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Session ID","name":"id","in":"path"}],"responses":{"200":{"description":"Session details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionDetail"}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"patch":{"summary":"Update session","description":"Update session metadata (title, notes, tags, favorite, action_items). At least one field is required. Requires the `sessions:write` scope.\n\n**Action items round-trip.** Pass a full `action_items` array to replace the list. Each item needs `text`; `id`, `source`, `assignee`, `due_date`, and `completed` are optional. Items with a known `id` preserve their original `created_at`, `source` and `source_start`. Omit `id` for new items and the server assigns one.\n\n`due_date` is stored as an ISO calendar date (`YYYY-MM-DD`). Send ISO, or natural language such as \"Friday\", \"next Tuesday\" or \"April 25\" and the server normalizes it relative to today; `null` or `\"\"` clears it, and an unparseable value is rejected with `400 invalid_request`. When a known item's `text` or normalized `due_date` changes, the server stamps `user_edited_at` (epoch ms) so Wave's extraction pipeline leaves hand-edited items alone.\n\nFor optimistic concurrency on `action_items`, send `If-Match: <action_items_version>`; the request is rejected with `409 conflict` if another writer has bumped the version in between. Skip the header to force-overwrite.","tags":["Sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID","example":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Session ID","name":"id","in":"path"},{"schema":{"type":"string","description":"Expected current `action_items_version` (optional). Returns 409 if it disagrees.","example":"2"},"required":false,"description":"Expected current `action_items_version` (optional). Returns 409 if it disagrees.","name":"If-Match","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchSessionRequest"}}}},"responses":{"200":{"description":"Session updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchSessionResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"409":{"description":"action_items_version conflict (If-Match mismatch)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"delete":{"summary":"Delete session","description":"Permanently delete a session. Storage files are cleaned up asynchronously.","tags":["Sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID","example":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Session ID","name":"id","in":"path"}],"responses":{"200":{"description":"Session deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteSessionResponse"}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/action-items":{"get":{"summary":"Get session action items","description":"Return the structured action_items for a session plus the current `version`. Use the returned `version` as `If-Match` on a subsequent PATCH to reject concurrent edits.","tags":["Sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID"},"required":true,"description":"Session ID","name":"id","in":"path"}],"responses":{"200":{"description":"Action items list + version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionItemsResponse"}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/transcript":{"get":{"summary":"Get session transcript","description":"Returns the full transcript as a flat string plus optional `segments[]` with per-turn speaker labels and start/end times in seconds (floats, not ISO timestamps). Use the flat string for LLM input; use segments for timestamped UIs.","tags":["Transcripts"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID","example":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Session ID","name":"id","in":"path"}],"responses":{"200":{"description":"Transcript","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptResponse"}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/media":{"get":{"summary":"Get session media URLs","description":"Get time-limited signed URLs for session audio and video files. URLs expire after 1 hour.","tags":["Media"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Session ID","example":"sess_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Session ID","name":"id","in":"path"}],"responses":{"200":{"description":"Signed media URLs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaResponse"}}}},"404":{"description":"Session not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/search":{"post":{"summary":"Search sessions","description":"Semantic search across all sessions using vector similarity. Each result includes a `snippet` — useful for triage without pulling the full session. Pass `tags` + `tag_mode` to restrict the vector search to sessions carrying specific tags (exact, case-sensitive).","tags":["Sessions"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResponse"}}}}}}},"/v1/sessions/stats":{"get":{"summary":"Get session statistics","description":"Get aggregated session statistics for a date range (default: last 30 days).","tags":["Sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Start date (ISO 8601, default: 30 days ago)","example":"2025-03-22T00:00:00.000Z"},"required":false,"description":"Start date (ISO 8601, default: 30 days ago)","name":"since","in":"query"},{"schema":{"type":"string","description":"End date (ISO 8601, default: now)","example":"2025-04-21T00:00:00.000Z"},"required":false,"description":"End date (ISO 8601, default: now)","name":"until","in":"query"}],"responses":{"200":{"description":"Session statistics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}}}}},"/v1/sessions/bulk":{"post":{"summary":"Bulk export sessions","description":"Fetch multiple sessions by ID in a single request. Max 50 session IDs per request. Set `include_transcript: true` to include full transcripts in the response (requires the `transcripts:read` scope). Ideal for backfilling a knowledge base from history.","tags":["Sessions"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkExportRequest"}}}},"responses":{"200":{"description":"Bulk export results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkExportResponse"}}}}}}},"/v1/account":{"get":{"summary":"Get account info","description":"Get user profile information including subscription status and session count.","tags":["Account"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountResponse"}}}}}}},"/v1/events":{"get":{"summary":"List events since cursor","description":"Pull events the caller has not yet acknowledged. The server tracks a per-token cursor so clients do not have to maintain their own dedupe state — the hard-won lesson that motivated this endpoint. Pass `cursor` explicitly to replay from a known point; omit it to resume from the token's last ack.\n\nUse with `POST /v1/events/ack` to advance the cursor. This is a drop-in alternative (or complement) to webhooks for integrators who prefer polling — same event shapes, same ids.\n\nEvent types match the webhooks subscription list: `session.completed`, `session.updated`, `session.deleted`, `session.action_items.updated`.","tags":["Events"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Integer seq. Events with seq > cursor are returned. Defaults to the token's last acknowledged position.","example":"4281"},"required":false,"description":"Integer seq. Events with seq > cursor are returned. Defaults to the token's last acknowledged position.","name":"cursor","in":"query"},{"schema":{"type":"string","description":"Max events (default 50, max 200)","example":"50"},"required":false,"description":"Max events (default 50, max 200)","name":"limit","in":"query"}],"responses":{"200":{"description":"Event list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EventsListResponse"}}}},"403":{"description":"Insufficient scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/events/ack":{"post":{"summary":"Acknowledge events through cursor","description":"Advance the caller's server-side cursor so future `GET /v1/events` calls skip events up to and including `cursor`. Acks are monotonic — a cursor lower than the currently persisted value is a no-op.","tags":["Events"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AckEventsRequest"}}}},"responses":{"200":{"description":"Cursor advanced","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AckEventsResponse"}}}},"400":{"description":"Invalid cursor","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/webhooks":{"get":{"summary":"List webhooks","description":"List all registered webhooks for the authenticated user.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Webhook list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookListResponse"}}}}}},"post":{"summary":"Create webhook","description":"Register a new webhook endpoint. The signing secret is only returned once at creation time. Max 5 webhooks per user.\n\n**Events**:\n- `session.completed` — fires once, after a session finishes processing and the summary, notes, and tags are queryable. This is the \"session is ready to use\" event.\n- `session.updated` — session metadata was changed (title, summary, notes, tags, favorite). Fires for edits from any source: the API, mobile app, or web app.\n- `session.action_items.updated` — structured action items on a session were written or edited via PATCH. Carries the full session in `data.session`, including the new `action_items` and `action_items_version`.\n- `session.deleted` — session was deleted (soft-delete or hard-delete of a completed session).","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}}},"responses":{"201":{"description":"Webhook created (includes secret)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"400":{"description":"Invalid request or limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/webhooks/{id}":{"patch":{"summary":"Update webhook","description":"Update webhook URL, events, or active status.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID","example":"wh_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PatchWebhookRequest"}}}},"responses":{"200":{"description":"Webhook updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"delete":{"summary":"Delete webhook","description":"Delete a webhook and clean up any pending deliveries.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID","example":"wh_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"responses":{"200":{"description":"Webhook deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteSessionResponse"}}}}}}},"/v1/webhooks/{id}/rotate-secret":{"post":{"summary":"Rotate webhook secret","description":"Regenerate the webhook signing secret. The new secret is returned in the response.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID","example":"wh_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"responses":{"200":{"description":"Secret rotated (includes new secret)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/webhooks/{id}/test":{"post":{"summary":"Test webhook","description":"Send a test event to the webhook endpoint and report delivery status.","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Webhook ID","example":"wh_01HX4R7MT8PQZ6VCN9ABYF2KJM"},"required":true,"description":"Webhook ID","name":"id","in":"path"}],"responses":{"200":{"description":"Test delivery result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestResponse"}}}},"404":{"description":"Webhook not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/shared-sessions":{"get":{"summary":"List sessions shared with me","description":"Requires the `sessions:read` scope. Default limit 20, maximum 100. Pages cover the latest 500 active grants. Pass next_cursor unchanged (base64url JSON of sharedAt ISO and grant ID). Shared sessions are read-only and excluded from search and folder/tag filters.","tags":["Shared sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","minimum":20,"maximum":100},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedSessionListResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/shared-sessions/{owner_id}/{id}":{"get":{"summary":"Get a shared session","description":"Requires the `sessions:read` scope. Summary and action_items are omitted when the grant scope excludes them. Revoked or missing access returns 404.","tags":["Shared sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"owner_id","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedSessionDetail"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/shared-sessions/{owner_id}/{id}/transcript":{"get":{"summary":"Get a shared transcript","description":"Requires the `transcripts:read` scope. Default segments returns speaker-labeled transcript plus available segments. text returns plain text; speaker_labeled returns speaker-labeled text. Excluded content returns 404.","tags":["Shared sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"owner_id","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["text","segments","speaker_labeled"]},"required":false,"name":"format","in":"query"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedTranscriptResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/shared-sessions/{owner_id}/{id}/action-items":{"get":{"summary":"Get shared action items","description":"Requires the `sessions:read` scope. Read-only; PATCH is 405. The callable omits edit provenance and timestamps. version is 0 and updated_at is null. Excluded content returns 404.","tags":["Shared sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"owner_id","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedActionItemsResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/shared-sessions/{owner_id}/{id}/media":{"get":{"summary":"Get shared media","description":"Requires the `media:read` scope. Media is signed on the owner path by the callable. Absent or excluded media returns 404 media_unavailable.","tags":["Shared sessions"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"owner_id","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SharedMediaResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/sharing":{"get":{"summary":"List session access","description":"Requires the `sharing:manage` scope. Owner only. link.url is always null: existing link tokens cannot be retrieved; create a link.","tags":["Sharing"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionSharingResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/sharing/link":{"post":{"summary":"Create a share link","description":"Requires the `sharing:manage` scope. Grants read access when claimed in the app. Link expires after 30 days. Invite tokens are not exposed as separate fields.","tags":["Sharing"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"responses":{"201":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinkResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/sharing/link/reset":{"post":{"summary":"Reset a share link","description":"Requires the `sharing:manage` scope. Invalidates the old link. remove_everyone also revokes all existing recipients.","tags":["Sharing"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetShareLinkRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetShareLinkResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/sharing/invites":{"post":{"summary":"Email share invites","description":"Requires the `sharing:manage` scope. Returns 200 even when all emails are skipped. Up to 10 emails and a 500-character message. Requires a verified account email.","tags":["Sharing"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendShareInvitesRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendShareInvitesResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}},"delete":{"summary":"Cancel a pending invite","description":"Requires the `sharing:manage` scope. Supply email in the JSON body or query string; optional invite_id targets a specific invite.","tags":["Sharing"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"email"},"required":false,"name":"email","in":"query"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelShareInviteRequest"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CancelShareInviteResponse"}}}},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}},"/v1/sessions/{id}/sharing/people/{recipient_id}":{"delete":{"summary":"Remove a shared person","description":"Requires the `sharing:manage` scope. Owner only; missing or trashed sessions return 404.","tags":["Sharing"],"security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","minLength":1},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1},"required":true,"name":"recipient_id","in":"path"}],"responses":{"204":{"description":"Person removed (no body)"},"400":{"description":"validation_error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"403":{"description":"Insufficient scope, no_access (owner only), sender_unverified, or account_required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"404":{"description":"not_found (including recipient no_access) or media_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"429":{"description":"sharing_rate_limited; handler message is preserved","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"500":{"description":"internal: impersonation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}},"503":{"description":"sharing_unavailable: timeout or upstream failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/APIError"}}}}}}}},"webhooks":{}}