{
  "openapi": "3.1.0",
  "info": {
    "title": "Nabrah Notetaker API",
    "version": "1.0.0",
    "description": "Record meetings, read transcripts, and pull structured notes into your own product.\n\nEvery response is wrapped in `data`; every failure in `error`. Anything belonging to another account answers 404, never 403 — an id can never be used to learn that a record exists."
  },
  "tags": [
    {
      "name": "Meetings",
      "description": "The calendar, and whether the notetaker will join each meeting."
    },
    {
      "name": "Bots",
      "description": "Sending the notetaker into a call, and pulling it out again."
    },
    {
      "name": "Recordings",
      "description": "Finished recordings: summaries, transcripts and action items."
    },
    {
      "name": "Calendar",
      "description": "Connecting a calendar and setting its auto-join rules."
    },
    {
      "name": "Uploads",
      "description": "Meetings recorded somewhere else."
    },
    {
      "name": "Organization",
      "description": "Seats, members and usage. Organization-wide keys only — an individual paying for a single seat has no team, so these stay 404 for them."
    },
    {
      "name": "Usage",
      "description": "Meetings and AI credits used this month, and what used them."
    },
    {
      "name": "Webhooks",
      "description": "Being told when something happens, instead of polling. Events: `meeting.started`, `meeting.ended`, `meeting.ready`, `meeting.failed`, `meeting.skipped` (a calendar meeting not recorded because the monthly limit was reached), `usage.threshold_reached` (80% or 100% of a limit; `scope` is `pool` for the team or account, `member` for a person's own limit), `calendar.connected`, `calendar.disconnected`, `calendar.reauth_required`."
    },
    {
      "name": "Account",
      "description": "Who the key acts as."
    }
  ],
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "An `nt_` key, issued from Dashboard → Developers. A read-only key may only issue GET."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "Me": {
        "type": "object",
        "properties": {
          "account": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              },
              "email": {
                "type": "string",
                "format": "email"
              }
            },
            "required": [
              "id",
              "name",
              "email"
            ]
          },
          "organization": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string"
              }
            }
          },
          "key": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "access": {
                "type": "string",
                "enum": [
                  "readonly",
                  "full"
                ]
              },
              "organizationWide": {
                "type": "boolean"
              }
            },
            "required": [
              "id",
              "access",
              "organizationWide"
            ]
          },
          "plan": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string"
              },
              "paid": {
                "type": "boolean"
              }
            },
            "required": [
              "key",
              "paid"
            ]
          }
        },
        "required": [
          "account",
          "organization",
          "key",
          "plan"
        ]
      },
      "Meeting": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "link": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "durationMinutes": {
            "type": "integer"
          },
          "source": {
            "type": "string",
            "enum": [
              "manual",
              "google",
              "webex",
              "microsoft"
            ]
          },
          "isAllDay": {
            "type": "boolean"
          },
          "isRecurring": {
            "type": "boolean"
          },
          "attendees": {
            "type": "array",
            "items": {
              "type": "object"
            }
          },
          "attendeeCount": {
            "type": "integer"
          },
          "organizer": {
            "type": [
              "object",
              "null"
            ]
          },
          "responseStatus": {
            "type": [
              "string",
              "null"
            ]
          },
          "externalUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "recordOverride": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "recordingDeleted": {
            "type": "boolean",
            "description": "An administrator deleted this occurrence's failed recording. The event stays on the calendar; no bot is sent to it again."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "title",
          "startsAt",
          "durationMinutes",
          "source",
          "createdAt"
        ]
      },
      "ScheduleRow": {
        "type": "object",
        "properties": {
          "meetingId": {
            "type": "string",
            "format": "uuid"
          },
          "runId": {
            "type": [
              "string",
              "null"
            ],
            "description": "The recording for this meeting. When a teammate's bot recorded the call, this is your own copy of its notes once they are ready."
          },
          "platform": {
            "type": [
              "string",
              "null"
            ]
          },
          "phase": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "skipReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "willRecord": {
            "type": "boolean"
          },
          "detail": {
            "type": [
              "string",
              "null"
            ]
          },
          "waitedSeconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "recordingSeconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "joinedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasNotes": {
            "type": "boolean"
          }
        },
        "required": [
          "meetingId",
          "willRecord",
          "hasNotes"
        ]
      },
      "Recording": {
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string",
            "pattern": "^NB-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}$"
          },
          "meetingId": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "platform": {
            "type": "string"
          },
          "origin": {
            "type": "string",
            "enum": [
              "calendar",
              "manual",
              "upload"
            ]
          },
          "state": {
            "type": "string"
          },
          "phase": {
            "type": "string"
          },
          "recordingSeconds": {
            "type": [
              "integer",
              "null"
            ]
          },
          "endedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasNotes": {
            "type": "boolean"
          }
        },
        "required": [
          "runId",
          "reference",
          "startsAt",
          "platform",
          "origin",
          "state",
          "hasNotes"
        ]
      },
      "ActionItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "title": {
            "type": "string"
          },
          "owner": {
            "type": [
              "string",
              "null"
            ]
          },
          "due": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string"
          },
          "context": {
            "type": [
              "string",
              "null"
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "title",
          "status"
        ]
      },
      "Connection": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "provider": {
            "type": "string",
            "enum": [
              "google",
              "webex",
              "microsoft"
            ],
            "description": "The calendar this connection reads. `microsoft` is Outlook / Microsoft 365, which carries Teams meetings."
          },
          "accountEmail": {
            "type": "string"
          },
          "calendarId": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "needs_reauth",
              "revoked"
            ]
          },
          "autoJoin": {
            "type": "string",
            "enum": [
              "all",
              "hosted",
              "manual"
            ]
          },
          "joinRules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Rule"
            }
          },
          "barRules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Rule"
            }
          },
          "lastSyncedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastError": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "provider",
          "accountEmail",
          "status",
          "autoJoin",
          "createdAt"
        ]
      },
      "Rule": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "enum": [
              "title",
              "email",
              "domain"
            ]
          },
          "value": {
            "type": "string"
          }
        },
        "required": [
          "kind",
          "value"
        ]
      },
      "Upload": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "runId": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string"
          },
          "title": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "audio",
              "transcript"
            ]
          },
          "stage": {
            "type": "string",
            "enum": [
              "pending",
              "stored",
              "transcribing",
              "analyzing",
              "ready",
              "failed"
            ]
          },
          "filename": {
            "type": "string"
          },
          "byteSize": {
            "type": [
              "integer",
              "null"
            ]
          },
          "durationMs": {
            "type": [
              "integer",
              "null"
            ]
          },
          "startsAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "error": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasNotes": {
            "type": "boolean"
          },
          "usage": {
            "$ref": "#/components/schemas/UsageInResponse",
            "description": "Only on create: what is left after this upload was counted."
          }
        },
        "required": [
          "id",
          "runId",
          "reference",
          "kind",
          "stage",
          "filename",
          "hasNotes"
        ]
      },
      "WebhookEndpoint": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "disabled"
            ]
          },
          "consecutiveFailures": {
            "type": "integer"
          },
          "lastDeliveryAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastStatus": {
            "type": [
              "integer",
              "null"
            ]
          },
          "disabledReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "status",
          "consecutiveFailures",
          "createdAt"
        ]
      },
      "UsageInResponse": {
        "type": "object",
        "description": "What is left after this request, so a caller can check before sending the next one.",
        "properties": {
          "remaining": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Meetings left this month. `null` is unlimited."
          },
          "maxMinutes": {
            "type": "integer",
            "description": "The bot leaves, or the upload is refused, past this many minutes."
          },
          "resetsAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the monthly limits reset."
          }
        },
        "required": [
          "remaining",
          "maxMinutes",
          "resetsAt"
        ]
      },
      "UsageMeter": {
        "type": "object",
        "properties": {
          "used": {
            "type": "integer",
            "description": "Everything used this month, including what bonus credits paid for."
          },
          "planUsed": {
            "type": "integer",
            "description": "The part of `used` the plan paid for. Compare this, not `used`, with `allowance`."
          },
          "allowance": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The plan's monthly allowance for the account or team. `null` is unlimited."
          },
          "available": {
            "type": [
              "integer",
              "null"
            ],
            "description": "What this person can still start: plan left plus their bonus. `null` is unlimited."
          },
          "bonus": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "remaining": {
                  "type": "integer"
                },
                "expiresAt": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "date-time"
                }
              }
            },
            "description": "Bonus credits granted to this person, soonest expiry first."
          },
          "mine": {
            "type": "integer",
            "description": "This person's share of `used` in a team."
          },
          "minePlan": {
            "type": "integer",
            "description": "The part of `mine` measured against `myLimit`."
          },
          "myLimit": {
            "type": [
              "integer",
              "null"
            ],
            "description": "A limit the team set for this person, if any."
          },
          "beforeJoining": {
            "type": "integer",
            "description": "Used this month before joining the team; it still counts."
          },
          "reached": {
            "type": "boolean"
          },
          "blockedBy": {
            "type": "string",
            "enum": [
              "pool",
              "member"
            ],
            "description": "Which limit this person meets first."
          }
        }
      },
      "Usage": {
        "type": "object",
        "properties": {
          "period": {
            "type": "string",
            "format": "date",
            "description": "The month counted, as its first day."
          },
          "resetsAt": {
            "type": "string",
            "format": "date-time"
          },
          "planRenewsAt": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The billing date, when on a paid subscription."
          },
          "plan": {
            "type": "object",
            "properties": {
              "key": {
                "type": "string"
              },
              "version": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "currentVersion": {
                "type": [
                  "integer",
                  "null"
                ]
              },
              "onOlderVersion": {
                "type": "boolean"
              }
            }
          },
          "pool": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "org",
                  "user"
                ]
              },
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "seats": {
                "type": "integer"
              },
              "seatsBasis": {
                "type": "string",
                "enum": [
                  "billed",
                  "live",
                  "single"
                ]
              }
            }
          },
          "custom": {
            "type": "object",
            "properties": {
              "meetings": {
                "type": "boolean"
              },
              "minutes": {
                "type": "boolean"
              },
              "credits": {
                "type": "boolean"
              }
            }
          },
          "meetings": {
            "$ref": "#/components/schemas/UsageMeter"
          },
          "aiCredits": {
            "$ref": "#/components/schemas/UsageMeter"
          },
          "minutesPerMeeting": {
            "type": [
              "integer",
              "null"
            ],
            "description": "The plan's cap per meeting. `null` falls back to `maxMinutes`."
          },
          "maxMinutes": {
            "type": "integer"
          },
          "creditCost": {
            "type": "object",
            "properties": {
              "single": {
                "type": "integer"
              },
              "all": {
                "type": "integer"
              }
            },
            "description": "AI credits one question costs: about one meeting, or across all meetings."
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "meetingId": {
                  "type": "string",
                  "format": "uuid"
                },
                "startsAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            },
            "description": "Calendar meetings not recorded this month because the limit was reached."
          }
        }
      },
      "BotStarted": {
        "type": "object",
        "properties": {
          "runId": {
            "type": "string",
            "format": "uuid"
          },
          "reference": {
            "type": "string"
          },
          "status": {
            "type": "string"
          },
          "phase": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "$ref": "#/components/schemas/UsageInResponse"
          }
        }
      }
    },
    "responses": {
      "Me": {
        "description": "The account behind the key.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/Me"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "Meeting": {
        "description": "One meeting.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/Meeting"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "MeetingPage": {
        "description": "A page of meetings.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Meeting"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "SchedulePage": {
        "description": "What is coming up, and what will be recorded.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ScheduleRow"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "MeetingPage1": {
        "description": "One meeting with its bot and notes.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "RecordingPage": {
        "description": "A page of recordings.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Recording"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "Notes": {
        "description": "A recording's summary and action items.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "TranscriptPage": {
        "description": "A page of utterances.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "ActionItemPage": {
        "description": "A page of action items.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ActionItem"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "ActionItem": {
        "description": "One action item.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "ConnectionPage": {
        "description": "A page of calendar connections.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Connection"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "Connection": {
        "description": "One calendar connection.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/Connection"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "ConnectLink": {
        "description": "A URL a person must open.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "UploadPage": {
        "description": "A page of uploads.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Upload"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "Upload": {
        "description": "One upload.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/Upload"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "OrgOverview": {
        "description": "Seats, usage and attention. `month.recordings` and `month.aiCredits.used` count only what the plan paid for; `fromBonus` is what bonus credits covered on top.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "MemberPage": {
        "description": "A page of members.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "Member": {
        "description": "One member.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "OrgAnalytics": {
        "description": "Counts and durations only. `totals`, `weeks`, `hours`, `platforms` and `members`, plus `insights`: the previous window's totals, join rate and recording lengths, meetings by weekday, where recordings came from, and AI questions.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "InvitePage": {
        "description": "Outstanding invitations.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "array"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "InviteResults": {
        "description": "One result per address.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "array"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "WebhookPage": {
        "description": "A page of endpoints.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/WebhookEndpoint"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "Webhook": {
        "description": "One endpoint.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "WebhookCreated": {
        "description": "The endpoint, with its signing secret — returned once and never again.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/WebhookEndpoint"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "WebhookQueued": {
        "description": "The test delivery was queued.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "DeliveryPage": {
        "description": "A page of delivery attempts.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object",
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "total": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "rows",
                    "total",
                    "limit",
                    "offset"
                  ]
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "BotStarted": {
        "description": "The bot was dispatched. `usage` carries meetings left, the minutes cap, and when limits reset.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/BotStarted"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "Usage": {
        "description": "This month's usage for the key's account. `planUsed` is what counts against `allowance`; `used` also includes bonus credits.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/Usage"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "UsageActivity": {
        "description": "A cursor page of usage rows: `{ rows, nextCursor }`.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "UsageRefused": {
        "description": "Refused, always 409 — never 429. `code` is `RECORDING_QUOTA_REACHED` (this month's meetings are used), `UPLOAD_PENDING_LIMIT` (three uploads are still waiting for their file), `MEETING_TOO_LONG` (longer than the plan's minutes per meeting), `MEETING_TOO_SHORT` (audio under 2 minutes), `UPLOAD_EXPIRED` (the file came too late), `USAGE_RETRY` (the team changed while this was being counted — send it again) or `CONFLICT` (this upload already has its file). Usage refusals are never remembered by `Idempotency-Key`, so the same request succeeds once the limit allows it.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Deleted": {
        "description": "Done.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "data": {
                  "type": "object"
                }
              },
              "required": [
                "data"
              ]
            }
          }
        }
      },
      "AlreadyRecordingOrCapped": {
        "description": "A bot is already live for this account (`ALREADY_RECORDING`), a colleague's bot is in this call (`TEAM_ALREADY_RECORDING`), the monthly meetings are used (`RECORDING_QUOTA_REACHED`), or the team changed while this was being counted (`USAGE_RETRY` — send it again). Usage refusals are never remembered by `Idempotency-Key`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RetryRefused": {
        "description": "Refused, always 409. `code` is `MEETING_TOO_LONG` (the file is over the plan's minutes per meeting), `RECORDING_QUOTA_REACHED` (a retry counts as a meeting again when the first attempt was not charged, and this month's are used), `USAGE_RETRY` (send it again) or `CONFLICT` (the upload has not stopped yet).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "No key, an unknown key, or one that has been revoked or has expired.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The key is read only, or lacks the reach for this route.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "No such record — or one that belongs to another account.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ValidationError": {
        "description": "The body or query failed validation; `details` names the field.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Too many requests. `Retry-After` says how long to wait.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "apiKey": []
    }
  ],
  "servers": [
    {
      "url": "https://api-notetaker.nabrah.ai/ext/v1"
    }
  ],
  "paths": {
    "/me": {
      "get": {
        "operationId": "getMe",
        "tags": [
          "Account"
        ],
        "summary": "See which account this key acts as",
        "description": "Returns the account the key belongs to, the organization it reaches if it is organization-wide, its access level, and the plan in force. Use it to confirm a key is live and to discover whether organization endpoints are available to it.\n\n`organization` being null does not mean the account is on a free plan. An individual can hold a paid subscription on a single seat, with no team: `plan.paid` is then true while `organization` stays null, `key.organizationWide` is false, and every `/organization` endpoint answers 404. Read `plan`, never the presence of `organization`, to decide what an account is entitled to.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Me"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/meetings": {
      "get": {
        "operationId": "listMeetings",
        "tags": [
          "Meetings"
        ],
        "summary": "List meetings on the calendar",
        "description": "Meetings as they appear on the connected calendar, whether or not the notetaker will join them. Omitting `from` and `to` returns everything held. Meetings the owner has removed from Nabrah are never listed.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/MeetingPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 200,
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          }
        ]
      },
      "post": {
        "operationId": "createMeeting",
        "tags": [
          "Meetings"
        ],
        "summary": "Add a meeting by hand",
        "description": "For a meeting that is not on a connected calendar. The link must be a Google Meet, Webex or Microsoft Teams URL; anything else is refused rather than stored and silently never recorded.",
        "responses": {
          "201": {
            "$ref": "#/components/responses/Meeting"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "link": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "startsAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                  },
                  "durationMinutes": {
                    "default": 30,
                    "type": "integer",
                    "minimum": 5,
                    "maximum": 1440
                  }
                },
                "required": [
                  "title",
                  "link",
                  "startsAt"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/meetings/schedule": {
      "get": {
        "operationId": "getSchedule",
        "tags": [
          "Meetings"
        ],
        "summary": "See what is coming up, and what will be recorded",
        "description": "Each meeting in the window with `willRecord`, and when false a `skipReason` naming why — the same decision the recording engine itself makes, resolved as you ask rather than looked up afterwards. This is the endpoint to answer \"will this be recorded\". The window may not exceed 92 days.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/SchedulePage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
            }
          }
        ]
      }
    },
    "/meetings/{id}": {
      "get": {
        "operationId": "getMeeting",
        "tags": [
          "Meetings"
        ],
        "summary": "Read one meeting",
        "description": "The meeting, the bot sent to it if any, why no bot was sent if none was, and the notes once they exist.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/MeetingPage1"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "patch": {
        "operationId": "updateMeeting",
        "tags": [
          "Meetings"
        ],
        "summary": "Change a meeting, or force recording on or off",
        "description": "`recordOverride` outranks every auto-join rule and survives calendar re-syncs, because the sync never writes that column. `true` records it regardless of the rules, `false` never records it, `null` hands the decision back to the connection's join mode.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Meeting"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "link": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "description": {
                    "anyOf": [
                      {
                        "type": "string",
                        "maxLength": 2000
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "startsAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                  },
                  "durationMinutes": {
                    "type": "integer",
                    "minimum": 5,
                    "maximum": 1440
                  },
                  "recordOverride": {
                    "anyOf": [
                      {
                        "type": "boolean"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "delete": {
        "operationId": "removeMeeting",
        "tags": [
          "Meetings"
        ],
        "summary": "Remove a meeting from Nabrah",
        "description": "A meeting added by hand is deleted. One that came from a connected calendar is tombstoned instead — deleting it outright would only have the next sync bring it back. Either way it stops appearing and no bot will be sent.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/bots": {
      "get": {
        "operationId": "listBots",
        "tags": [
          "Bots"
        ],
        "summary": "List bot runs",
        "description": "Every recording this account has, newest first — the same rows as `/recordings`, under the noun that fits what you are doing with them.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/RecordingPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "default": 0,
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          }
        ]
      },
      "post": {
        "operationId": "sendBot",
        "tags": [
          "Bots"
        ],
        "summary": "Send the notetaker into a meeting",
        "description": "Dispatches a bot to a live meeting link. Three things are worth knowing before you call it: only **one bot per account** can be live at a time, so a second call returns 409 and retrying will not help; it **counts against the monthly recording allowance**, and at the cap returns 409 with the reason; and the link must be on a supported platform. Send an `Idempotency-Key` so a retry after a timeout cannot start a second bot.",
        "responses": {
          "201": {
            "$ref": "#/components/responses/BotStarted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/AlreadyRecordingOrCapped"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "joinUrl": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "title": {
                    "type": "string",
                    "maxLength": 300
                  }
                },
                "required": [
                  "joinUrl"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/bots/{runId}": {
      "get": {
        "operationId": "getBot",
        "tags": [
          "Bots"
        ],
        "summary": "Check on a bot",
        "description": "Whether it has joined, how long it has been recording, and what it is doing now.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/MeetingPage1"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/bots/{runId}/stop": {
      "post": {
        "operationId": "stopBot",
        "tags": [
          "Bots"
        ],
        "summary": "Pull the notetaker out of a call",
        "description": "Ends the recording early. Whatever was captured up to that point is still processed into notes. A run that has already finished answers 404, because there is nothing left to stop.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/recordings": {
      "get": {
        "operationId": "listRecordings",
        "tags": [
          "Recordings"
        ],
        "summary": "List recordings",
        "description": "Every recording, newest first — from calendar meetings, manual joins and uploads alike. A run superseded by a rescheduled meeting is left out, so one meeting never appears twice.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/RecordingPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "default": 0,
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          }
        ]
      }
    },
    "/recordings/{runId}": {
      "get": {
        "operationId": "getRecording",
        "tags": [
          "Recordings"
        ],
        "summary": "Read a recording's summary and action items",
        "description": "The summary, attendees, topics and action items. **The transcript is left out by default** — it is far larger than everything else combined, and most callers never look at it. Add `?include=transcript` when you want it, or use the transcript endpoint to page through it.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Notes"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/recordings/{runId}/transcript": {
      "get": {
        "operationId": "getTranscript",
        "tags": [
          "Recordings"
        ],
        "summary": "Read the transcript",
        "description": "Utterances in order, with speaker and millisecond offsets, paged. A recording shared with you without its transcript returns an empty list and says so in `scope`, rather than pretending there was nothing said.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/TranscriptPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "default": 0,
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/recordings/{runId}/action-items": {
      "get": {
        "operationId": "listActionItems",
        "tags": [
          "Recordings"
        ],
        "summary": "List a recording's action items",
        "description": "What the analysis pulled out as things to do, with owner and due date where it could tell.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionItemPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/recordings/{runId}/audio": {
      "get": {
        "operationId": "getAudio",
        "tags": [
          "Recordings"
        ],
        "summary": "Download the audio",
        "description": "Streams the recording, honouring `Range` so a player can seek. Requires the audio: a recording shared with you without it answers 404.",
        "responses": {
          "200": {
            "description": "The audio itself. `Content-Type` is whatever was stored: `audio/mpeg`, `audio/mp4`, `audio/webm` and `audio/ogg` are the ones we produce.",
            "headers": {
              "Accept-Ranges": {
                "description": "Always `bytes`, so a player can seek.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "audio/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "206": {
            "description": "The bytes asked for, when the request carried a `Range`.",
            "headers": {
              "Content-Range": {
                "description": "Which bytes these are, of how many.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "audio/*": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/action-items/{itemId}": {
      "patch": {
        "operationId": "setActionItemStatus",
        "tags": [
          "Recordings"
        ],
        "summary": "Tick an action item, or reopen it",
        "description": "Marks the item done or active. Doing this also marks the item as a person's rather than the model's, which is what stops a later re-analysis of the same meeting from quietly reopening it.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/ActionItem"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "active",
                      "done"
                    ]
                  }
                },
                "required": [
                  "status"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/calendar/connections": {
      "get": {
        "operationId": "listConnections",
        "tags": [
          "Calendar"
        ],
        "summary": "List connected calendars",
        "description": "Which calendars are connected, their sync health, and the auto-join rules on each. Never carries an access token, a sync token or a webhook secret.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/ConnectionPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/calendar/connections/{id}": {
      "get": {
        "operationId": "getConnection",
        "tags": [
          "Calendar"
        ],
        "summary": "Read one connection",
        "description": "One calendar connection: which account and calendar it covers, whether it is still syncing, when it last did, and the auto-join mode and rules currently in force on it. A connection belonging to another account answers 404.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Connection"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "patch": {
        "operationId": "updateConnection",
        "tags": [
          "Calendar"
        ],
        "summary": "Set auto-join mode and rules",
        "description": "`autoJoin` is `all`, `hosted` (only meetings this account organises) or `manual` (never automatically). `barRules` are checked before `joinRules`, so a bar always wins. Rule values are lowercased and trimmed on the way in, so they match how meetings are compared.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Connection"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "autoJoin": {
                    "type": "string",
                    "enum": [
                      "all",
                      "hosted",
                      "manual"
                    ]
                  },
                  "joinRules": {
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "title",
                            "email",
                            "domain"
                          ]
                        },
                        "value": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        }
                      },
                      "required": [
                        "kind",
                        "value"
                      ]
                    }
                  },
                  "barRules": {
                    "maxItems": 20,
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "title",
                            "email",
                            "domain"
                          ]
                        },
                        "value": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        }
                      },
                      "required": [
                        "kind",
                        "value"
                      ]
                    }
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "delete": {
        "operationId": "disconnectCalendar",
        "tags": [
          "Calendar"
        ],
        "summary": "Disconnect a calendar",
        "description": "Revokes the grant with the provider and stops syncing. Recordings already made are unaffected — they hang off the run, not the calendar.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/calendar/connect-links": {
      "post": {
        "operationId": "createConnectLink",
        "tags": [
          "Calendar"
        ],
        "summary": "Start connecting a calendar",
        "description": "Returns a URL that a **person** must open in a browser to grant access. This cannot be completed headlessly — there is no way to connect a calendar from a server alone. Hand the link to your user, then poll the connection list or take the `calendar.connected` webhook to learn when it finished.",
        "responses": {
          "201": {
            "$ref": "#/components/responses/ConnectLink"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "provider": {
                    "type": "string",
                    "enum": [
                      "google",
                      "webex",
                      "microsoft"
                    ],
                    "description": "google: Google Calendar. microsoft: Outlook / Microsoft 365, which is where Teams meetings live. webex: Webex."
                  }
                },
                "required": [
                  "provider"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/uploads": {
      "get": {
        "operationId": "listUploads",
        "tags": [
          "Uploads"
        ],
        "summary": "List uploads",
        "description": "Meetings recorded elsewhere and sent here, with how far through processing each one is.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/UploadPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "default": 0,
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          }
        ]
      },
      "post": {
        "operationId": "createUpload",
        "tags": [
          "Uploads"
        ],
        "summary": "Register a recording made elsewhere",
        "description": "The first of two requests: this creates the row and decides from the file name whether it is audio or a transcript. Send the bytes to the content endpoint afterwards. Counts as a meeting in the month it is made, whatever `startsAt` says. The response carries `usage` — meetings left, the minutes cap, and when limits reset — so you can check a file's length before sending it. At most three uploads may wait for their file at once.",
        "responses": {
          "201": {
            "$ref": "#/components/responses/Upload"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/UsageRefused"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 300
                  },
                  "filename": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "contentType": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "byteSize": {
                    "type": "integer",
                    "exclusiveMinimum": 0,
                    "maximum": 9007199254740991
                  },
                  "startsAt": {
                    "type": "string",
                    "format": "date-time",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "audio",
                      "transcript"
                    ]
                  }
                },
                "required": [
                  "filename"
                ]
              }
            }
          }
        }
      }
    },
    "/uploads/{uploadId}": {
      "get": {
        "operationId": "getUpload",
        "tags": [
          "Uploads"
        ],
        "summary": "Check an upload's progress",
        "description": "Where the file has got to: stored, transcribing, analysing, ready or failed. `hasNotes` is what tells you the notes can be read.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Upload"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "uploadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "delete": {
        "operationId": "removeUpload",
        "tags": [
          "Uploads"
        ],
        "summary": "Delete an upload",
        "description": "Removes the upload and everything derived from it — the recording, its notes and its transcript.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "uploadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/uploads/{uploadId}/content": {
      "put": {
        "operationId": "uploadContent",
        "tags": [
          "Uploads"
        ],
        "summary": "Send the file",
        "description": "The raw body is the file — not multipart, not base64. Audio is streamed straight through and never buffered, so a large file is fine. Whether this is read as audio or as a transcript was settled when the row was created, from the file name; sending the wrong kind is refused rather than guessed at. A recording longer than the plan's minutes per meeting is refused with `MEETING_TOO_LONG`, and audio under 2 minutes with `MEETING_TOO_SHORT`; neither counts.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Upload"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/UsageRefused"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "uploadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/uploads/{uploadId}/retry": {
      "post": {
        "operationId": "retryUpload",
        "tags": [
          "Uploads"
        ],
        "summary": "Retry a failed upload",
        "description": "Re-runs processing on the file already stored; nothing is re-sent. If the first attempt was not counted against the month (it failed before analysis), the retry counts as a meeting.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Upload"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/RetryRefused"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "uploadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/organization": {
      "get": {
        "operationId": "getOrganization",
        "tags": [
          "Organization"
        ],
        "summary": "Seats, usage and what needs attention",
        "description": "The organization's plan, seats used against seats held, this month's recordings and minutes against the allowance, and counts of things wanting a manager. `recordings` is the part the allowance paid for; anything bonus credits covered is in `fromBonus` and is not counted against it, so `recordings` never exceeds `allowance`. Requires an organization-wide key; a personal key answers 404.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/OrgOverview"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/organization/members": {
      "get": {
        "operationId": "listMembers",
        "tags": [
          "Organization"
        ],
        "summary": "List members",
        "description": "Who is in the organization, their role, what they have recorded this month and the limits in force for them.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/MemberPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "term",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          },
          {
            "name": "role",
            "in": "query",
            "required": false,
            "schema": {
              "default": "all",
              "type": "string",
              "enum": [
                "all",
                "owner",
                "admin",
                "member"
              ]
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "schema": {
              "default": "joined",
              "type": "string",
              "enum": [
                "joined",
                "busiest"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "default": 0,
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          }
        ]
      }
    },
    "/organization/members/{userId}": {
      "get": {
        "operationId": "getMember",
        "tags": [
          "Organization"
        ],
        "summary": "Read one member",
        "description": "One member's usage and effective limits. A user id outside this organization answers 404, so an id cannot be used to probe for accounts elsewhere.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Member"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/organization/analytics": {
      "get": {
        "operationId": "getOrganizationAnalytics",
        "tags": [
          "Organization"
        ],
        "summary": "Usage over time",
        "description": "Counts and durations across the organization: totals, by week, by hour of day, by platform, and per member. **Never meeting content** — no titles, no attendees, no transcripts, and no ids that could be used to fetch any.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/OrgAnalytics"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "default": 30,
              "type": "integer",
              "minimum": -9007199254740991,
              "maximum": 9007199254740991
            }
          }
        ]
      }
    },
    "/organization/invites": {
      "get": {
        "operationId": "listInvites",
        "tags": [
          "Organization"
        ],
        "summary": "List outstanding invitations",
        "description": "Who has been asked to join and has not yet accepted, with when each invitation lapses.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/InvitePage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createInvites",
        "tags": [
          "Organization"
        ],
        "summary": "Invite people",
        "description": "Sends an invitation to each address. Each result says what happened to that one: `sent`, `already_member`, `self`, `seat_limit` when the team has no seat left for it (members and open invitations count against the limit, 5 unless arranged otherwise), or `failed` with a reason — one bad address does not fail the rest. A key can invite an admin or a member, never an owner.",
        "responses": {
          "201": {
            "$ref": "#/components/responses/InviteResults"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "emails": {
                    "minItems": 1,
                    "maxItems": 50,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email",
                      "pattern": "^(?!\\.)(?!.*\\.\\.)([A-Za-z0-9_'+\\-\\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                    }
                  },
                  "role": {
                    "default": "member",
                    "type": "string",
                    "enum": [
                      "admin",
                      "member"
                    ]
                  }
                },
                "required": [
                  "emails"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhook endpoints",
        "description": "Your registered endpoints, their health, and why any of them was disabled. Never returns the signing secret.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/WebhookPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      },
      "post": {
        "operationId": "createWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Register a webhook endpoint",
        "description": "**The signing secret is in this response and in no other.** Store it before you close the connection; it cannot be retrieved afterwards. The URL must be https on port 443 and must resolve to a public address — it is re-checked on every delivery, not only here.",
        "responses": {
          "201": {
            "$ref": "#/components/responses/WebhookCreated"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "events": {
                    "minItems": 1,
                    "maxItems": 9,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "meeting.started",
                        "meeting.ended",
                        "meeting.ready",
                        "meeting.failed",
                        "calendar.connected",
                        "calendar.disconnected",
                        "calendar.reauth_required",
                        "meeting.skipped",
                        "usage.threshold_reached"
                      ]
                    }
                  }
                },
                "required": [
                  "url",
                  "events"
                ],
                "additionalProperties": false
              }
            }
          }
        }
      }
    },
    "/webhooks/{id}": {
      "get": {
        "operationId": "getWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Read one endpoint",
        "description": "Its events, its recent delivery health, and — if we stopped sending to it — the reason.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Webhook"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "patch": {
        "operationId": "updateWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Change an endpoint, or re-enable it",
        "description": "Change the URL or the events. Sending `status: \"active\"` re-enables an endpoint we disabled and clears its failure count — without clearing it, one more failure would disable it again immediately.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Webhook"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "maxLength": 2048,
                    "format": "uri"
                  },
                  "events": {
                    "minItems": 1,
                    "maxItems": 9,
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "meeting.started",
                        "meeting.ended",
                        "meeting.ready",
                        "meeting.failed",
                        "calendar.connected",
                        "calendar.disconnected",
                        "calendar.reauth_required",
                        "meeting.skipped",
                        "usage.threshold_reached"
                      ]
                    }
                  },
                  "status": {
                    "type": "string",
                    "const": "active"
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      },
      "delete": {
        "operationId": "deleteWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete an endpoint",
        "description": "Stops delivery immediately and removes the endpoint along with its delivery history. Events already queued for it are dropped. There is no way to undo this — register a new endpoint instead, which will have a new signing secret.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Deleted"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/webhooks/{id}/test": {
      "post": {
        "operationId": "testWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Send a test event",
        "description": "Queues one synthetic delivery, through the ordinary queue rather than a shortcut — so what you receive is exactly shaped like a real event, signature and all. A disabled endpoint answers 409.",
        "responses": {
          "202": {
            "$ref": "#/components/responses/WebhookQueued"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/usage": {
      "get": {
        "operationId": "getUsage",
        "tags": [
          "Usage"
        ],
        "summary": "See this month's usage",
        "description": "Meetings and AI credits used and available for the key's own account, bonus credits and when they expire, the minutes cap per meeting, when limits reset (the calendar month) and when the plan renews (the billing date). In a team the totals are the team's, and `mine` is this person's share. `null` means unlimited, never zero.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/Usage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/usage/activity": {
      "get": {
        "operationId": "listUsageActivity",
        "tags": [
          "Usage"
        ],
        "summary": "List what used meetings and credits",
        "description": "Newest first, one row per meeting or question, plus bonus credits granted. Paged by cursor: pass `nextCursor` back as `cursor`. A row released because nothing was recorded still appears, with `state: released`, so the history explains every number.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/UsageActivity"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "default": "all",
              "type": "string",
              "enum": [
                "all",
                "meeting",
                "ai_credit"
              ]
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 80
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          }
        ]
      }
    },
    "/webhooks/{id}/deliveries": {
      "get": {
        "operationId": "listDeliveries",
        "tags": [
          "Webhooks"
        ],
        "summary": "See what we tried to send",
        "description": "Every attempt on this endpoint with its status, timing and error — the first place to look when an event did not arrive.",
        "responses": {
          "200": {
            "$ref": "#/components/responses/DeliveryPage"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "422": {
            "$ref": "#/components/responses/ValidationError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "default": 25,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "default": 0,
              "type": "integer",
              "minimum": 0,
              "maximum": 9007199254740991
            }
          },
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    }
  }
}
