{"openapi":"3.1.0","info":{"title":"Notulen AI API","version":"1","description":"Send meetings in as a transcript, an audio URL, a file, or a live meeting link; read the minutes, transcript, and action items back; and be told when they are ready. Every request needs an API key (`Authorization: Bearer nk_…`) created under Integrations. A key reads and writes one organisation only."},"servers":[{"url":"https://notulen.cloud-ioh.com/api/v1"}],"tags":[{"name":"Meetings"},{"name":"Documents"},{"name":"Search and ask"},{"name":"Action items"},{"name":"Webhooks"},{"name":"Account"}],"paths":{"/me":{"get":{"tags":["Account"],"summary":"Check the key","description":"The organisation, the key’s scopes, and the processing queue. A personal access token (Account › Personal access tokens) acts as the person who made it and sees only the meetings they can open; `key.personal` and `user` tell it apart from an organisation key.","security":[{"bearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"organization":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"}}},"auth":{"type":"string","description":"“key” or “session”."},"scopes":{"type":"array","items":{"type":"string"}},"events":{"type":"array","items":{"type":"string"}},"key":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"personal":{"type":"boolean","description":"True for a personal access token."}}},"user":{"type":"object","nullable":true,"description":"The person a personal token or a session acts as.","properties":{"id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string"}}},"acting_as":{"type":"string","description":"The name written to the activity log for what this credential does."},"queue":{"$ref":"#/components/schemas/Queue"}}}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/status":{"get":{"tags":["Account"],"summary":"Is anything broken?","description":"One word (`health`), plus the last 24 hours of meetings, stuck meetings, recent failures, and webhook deliveries.","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"health":{"type":"string","description":"sehat | ada_kegagalan | perlu_diperiksa","enum":["sehat","ada_kegagalan","perlu_diperiksa"]},"at":{"type":"string","format":"date-time"},"queue":{"$ref":"#/components/schemas/Queue"},"meetings_24h":{"type":"object","additionalProperties":{"type":"integer"}},"meetings_stuck":{"type":"integer"}}}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/keys":{"get":{"tags":["Account"],"summary":"List API keys","description":"Names, prefixes, scopes, and last use. The keys themselves are never returned.","security":[{"bearer":["webhooks:manage"]}],"x-notulen-scope":"webhooks:manage","responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings":{"get":{"tags":["Meetings"],"summary":"List meetings","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["queued","downloading","transcribing","summarizing","done","failed"]},"description":"Only this status."},{"name":"since","in":"query","required":false,"schema":{"type":"string","format":"date-time"},"description":"Only meetings created at or after this time."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"How many to return."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"meetings":{"type":"array","items":{"$ref":"#/components/schemas/Meeting"}},"queue":{"$ref":"#/components/schemas/Queue"}}}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Meetings"],"summary":"Create a meeting","description":"Exactly one of `transcript` (no transcription cost), `audio_url` (the server downloads it), or `meeting_url` (the bot joins). Send an `Idempotency-Key` header from automations: a retried request then returns the first meeting instead of creating — and billing — a second one.\n\nOne bot per meeting: a `meeting_url` that a bot from this organisation is already recording does not send a second bot. An organisation key gets that meeting back (`200`, `existing: true`). A personal token gets it too when its person can already open it; otherwise the person who sent the bot is asked to share it (`202`, `status: \"access_requested\"`), unless the organisation lets people join recordings automatically.","security":[{"bearer":["meetings:write"]}],"x-notulen-scope":"meetings:write","x-notulen-billable":true,"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"transcript":{"type":"string","description":"Plain text, WebVTT, or SRT."},"audio_url":{"type":"string","format":"uri"},"meeting_url":{"type":"string","format":"uri"},"meeting_date":{"type":"string","description":"YYYY-MM-DD.","format":"date"},"language":{"type":"string","description":"e.g. “id” or “en”."},"participants":{"type":"string"},"agenda":{"type":"string"},"template_id":{"type":"string","description":"From GET /templates. Empty = the organisation default."}}}}}},"responses":{"200":{"description":"The meeting at `meeting_url` is already being recorded by your organisation; this is that meeting.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"existing":{"type":"boolean"},"joined":{"type":"boolean"},"queue_position":{"type":["integer","null"]}}}}}},"201":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"queue_position":{"type":["integer","null"]}}}}}},"202":{"description":"Already being recorded by a colleague’s bot; they were asked to share it with the token’s person.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":["string","null"]},"status":{"type":"string","enum":["access_requested"]},"existing":{"type":"boolean"},"join_request":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"owner":{"type":["string","null"]}}}}}}}},"400":{"description":"The body does not describe a meeting.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"The plan’s monthly minutes are used up.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A colleague’s bot is already recording that meeting, and the request to join it was just declined.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/upload":{"post":{"tags":["Meetings"],"summary":"Upload a recording","security":[{"bearer":["meetings:write"]}],"x-notulen-scope":"meetings:write","x-notulen-billable":true,"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["audio"],"properties":{"audio":{"type":"string","format":"binary"},"title":{"type":"string"},"meeting_date":{"type":"string","format":"date"},"language":{"type":"string"},"participants":{"type":"string"},"agenda":{"type":"string"},"template_id":{"type":"string"}}}}}},"responses":{"201":{"description":"OK"},"400":{"description":"No file, or an empty one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The file is larger than the server accepts.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}":{"get":{"tags":["Meetings"],"summary":"Get a meeting","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."},{"name":"transcript","in":"query","required":false,"schema":{"type":"boolean"},"description":"Include the transcript text."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MeetingDetail"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such meeting in this organisation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Meetings"],"summary":"Delete a meeting","description":"Moves the meeting to Trash, where it can be restored from the app until `purge_at`. `?permanent=true` deletes it immediately, with its audio.","security":[{"bearer":["meetings:write"]}],"x-notulen-scope":"meetings:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."},{"name":"permanent","in":"query","required":false,"schema":{"type":"boolean"},"description":"Skip Trash."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"trashed":{"type":"boolean"},"purge_at":{"type":"string","format":"date-time"}}}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such meeting in this organisation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/reprocess":{"post":{"tags":["Meetings"],"summary":"Rebuild a meeting","security":[{"bearer":["meetings:write"]}],"x-notulen-scope":"meetings:write","x-notulen-billable":true,"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"mom_only":{"type":"boolean","description":"Rewrite the minutes from the stored transcript; no transcription cost."},"template_id":{"type":"string"}}}}}},"responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The meeting is still being processed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/recap-image":{"post":{"tags":["Documents"],"summary":"Draw the AI recap card","description":"Draws the card, or returns the stored one. Counts against the key’s daily recap quota when a new image is drawn.","security":[{"bearer":["recap:generate"]}],"x-notulen-scope":"recap:generate","x-notulen-billable":true,"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"force":{"type":"boolean","description":"Redraw even if a card exists."},"style":{"type":"string","description":"A slug from GET /recap-styles."}}}}}},"responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/mom.md":{"get":{"tags":["Documents"],"summary":"Minutes as Markdown","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."}],"responses":{"200":{"description":"OK","content":{"text/markdown":{"schema":{"type":"string"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The minutes are not ready yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/mom.{format}":{"get":{"tags":["Documents"],"summary":"Minutes as Word or PDF","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."},{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["docx","pdf"]}}],"responses":{"200":{"description":"OK","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The minutes are not ready yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/transcript.{format}":{"get":{"tags":["Documents"],"summary":"Transcript as a file","description":"`txt` always works. `srt` and `vtt` need a transcript with timestamps.","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."},{"name":"format","in":"path","required":true,"schema":{"type":"string","enum":["txt","srt","vtt"]}}],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"string"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No transcript — never made, or removed by the retention policy.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The transcript has no timestamps; ask for txt.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/audio":{"get":{"tags":["Documents"],"summary":"The recording","description":"Supports Range requests. `?download=1` names the file after the meeting.","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."},{"name":"download","in":"query","required":false,"schema":{"type":"string","enum":["1"]},"description":"Send as a named download."}],"responses":{"200":{"description":"OK","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"The audio is not on the server — never was, or the retention policy removed it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/card":{"get":{"tags":["Documents"],"summary":"Adaptive Card for Teams","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."},{"name":"wrap","in":"query","required":false,"schema":{"type":"string","enum":["teams"]},"description":"Wrap as a Teams message attachment."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/recap.png":{"get":{"tags":["Documents"],"summary":"The stored recap card","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."}],"responses":{"200":{"description":"OK","content":{"image/png":{"schema":{"type":"string","format":"binary"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No card has been drawn yet.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/search":{"get":{"tags":["Search and ask"],"summary":"Search meetings","description":"Full-text search over titles, transcripts, and minutes, with snippets around the match.","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"What to look for."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50,"default":20},"description":"How many to return."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/meetings/{id}/ask":{"post":{"tags":["Search and ask"],"summary":"Ask one meeting","description":"Answers from that meeting’s transcript only, with verbatim quotes. One paid model call; counts against the plan’s monthly questions.","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","x-notulen-billable":true,"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Meeting id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Question"}}}},"responses":{"201":{"description":"Answered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Answer"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The meeting has no transcript.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"The transcript is too long to ask about.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/ask":{"post":{"tags":["Search and ask"],"summary":"Ask across meetings","description":"Finds the relevant meetings first, then answers from their minutes and transcript excerpts, citing each meeting. Not billed when no meeting matches.","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","x-notulen-billable":true,"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["question"],"properties":{"question":{"type":"string","maxLength":500},"days":{"type":"integer","description":"Only meetings from the last N days."},"tag":{"type":"string","description":"Only meetings with this tag."}}}}}},"responses":{"200":{"description":"Answered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Answer"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/templates":{"get":{"tags":["Meetings"],"summary":"List minutes templates","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/recap-styles":{"get":{"tags":["Documents"],"summary":"List recap card styles","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/action-items":{"get":{"tags":["Action items"],"summary":"List action items","security":[{"bearer":["meetings:read"]}],"x-notulen-scope":"meetings:read","parameters":[{"name":"owner","in":"query","required":false,"schema":{"type":"string"},"description":"Exact owner name."},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["open","in_progress","done"]},"description":"Only this status."},{"name":"overdue","in":"query","required":false,"schema":{"type":"string","enum":["true"]},"description":"Only items past their due date."}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ActionItem"}},"today":{"type":"string","description":"Today in the organisation’s time zone.","format":"date"}}}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/action-items/{id}":{"patch":{"tags":["Action items"],"summary":"Update an action item","security":[{"bearer":["actions:write"]}],"x-notulen-scope":"actions:write","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Action item id."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["open","in_progress","done"]},"owner":{"type":"string"},"due":{"type":"string"},"due_date":{"type":["string","null"],"format":"date"},"priority":{"type":"string","enum":["high","medium","low"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActionItem"}}}},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such action item.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"get":{"tags":["Webhooks"],"summary":"List webhooks and recent deliveries","security":[{"bearer":["webhooks:manage"]}],"x-notulen-scope":"webhooks:manage","responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Webhooks"],"summary":"Register a webhook","description":"The reply carries `secret` (for the HMAC signature) and `header_token` once — store them then.","security":[{"bearer":["webhooks:manage"]}],"x-notulen-scope":"webhooks:manage","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"https only.","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["*","meeting.completed","meeting.failed","recap.ready","mom.approved"]}},"include_card":{"type":"boolean","description":"Put the meeting card — its content — in the payload."}}}}}},"responses":{"201":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks/{id}":{"delete":{"tags":["Webhooks"],"summary":"Remove a webhook","security":[{"bearer":["webhooks:manage"]}],"x-notulen-scope":"webhooks:manage","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Webhook id."}],"responses":{"200":{"description":"OK"},"401":{"description":"Missing, unknown, or revoked API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key lacks the scope this operation needs, or the organisation’s plan does not include it.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such webhook.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit reached. The Retry-After header says when to try again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"An API key starting with nk_. Scopes: meetings:read, meetings:write, actions:write, recap:generate, webhooks:manage."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"string","description":"What went wrong, in a sentence a person can act on."},"code":{"type":"string","description":"Present for plan refusals: plan_feature, plan_limit, org_read_only."}}},"Queue":{"type":"object","properties":{"pending":{"type":"integer"},"running":{"type":"boolean"}}},"Meeting":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"source":{"type":"string","enum":["upload","record","bot","api"]},"status":{"type":"string","enum":["queued","downloading","transcribing","summarizing","done","failed"]},"error":{"type":["string","null"]},"language":{"type":["string","null"]},"meeting_date":{"type":["string","null"],"format":"date"},"duration_sec":{"type":["number","null"]},"meeting_url":{"type":["string","null"]},"provider":{"type":["string","null"]},"has_recap_image":{"type":"boolean"},"has_audio":{"type":"boolean"},"transcript_gaps":{"type":"array","items":{"type":"object"},"description":"Stretches of the recording that produced no transcript."},"mom_edited_at":{"type":["string","null"],"format":"date-time"},"mom_edited_by":{"type":["string","null"]},"approved_at":{"type":["string","null"],"description":"Set once someone has approved the minutes — the gate for sending them on.","format":"date-time"},"approved_by":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"MeetingDetail":{"allOf":[{"$ref":"#/components/schemas/Meeting"},{"type":"object","properties":{"queue_position":{"type":["integer","null"]},"mom":{"type":["object","null"],"description":"The structured minutes."},"mom_md":{"type":["string","null"]},"action_items":{"type":"array","items":{"$ref":"#/components/schemas/ActionItem"}},"transcript":{"type":"string","description":"Only with ?transcript=true."}}}]},"ActionItem":{"type":"object","properties":{"id":{"type":"string"},"meeting_id":{"type":"string"},"meeting_title":{"type":"string"},"task":{"type":"string"},"owner":{"type":["string","null"]},"due":{"type":["string","null"],"description":"The deadline as it was said."},"due_date":{"type":["string","null"],"format":"date"},"priority":{"type":["string","null"]},"status":{"type":"string","enum":["open","in_progress","done"]},"overdue":{"type":"boolean"},"external_key":{"type":["string","null"],"description":"e.g. a Jira issue key."},"external_url":{"type":["string","null"]}}},"Question":{"type":"object","required":["question"],"properties":{"question":{"type":"string","maxLength":500}}},"Answer":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"},"found":{"type":"boolean","description":"false = the meetings do not contain the answer."},"citations":{"type":"array","items":{"type":"object","properties":{"meeting_id":{"type":"string"},"title":{"type":"string"},"date":{"type":["string","null"]},"time":{"type":"string"},"speaker":{"type":"string"},"quote":{"type":"string","description":"Verbatim."}}}},"searched":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"date":{"type":["string","null"]}}}}}}}}}