// docs · rest api

REST API reference.

A small, predictable JSON API over your meetings. List them, fetch one with its transcript and outputs, search across every call, and ask a question of a single meeting. Bearer-token auth, JSON in and out.

Base URL

https://api.notabium.com/v1

Every path below is relative to that base. All responses are application/json.

Authentication

Authenticate with a Notabium API key, created in the app on the API keys page. Send it as a bearer token on every request:

Authorization: Bearer ntb_live_...

A request with no key, or an invalid or revoked key, returns 401. Keys are read and ask only (see scope below).

Scope and rate

API keys can use the read and ask endpoints on this page. They cannot create or delete meetings, change sharing, manage billing, or manage other API keys. Those need a signed-in session in the app and return 403 {"error":"session_required"} if attempted with a key. Manage and revoke your keys on the API keys page. Be reasonable with request volume; sustained heavy use may be throttled.

Endpoints

MethodPathWhat it does
GET/v1/meetingsList your recent meetings.
GET/v1/meetings/:idOne meeting with its transcript and outputs.
GET/v1/meetings/search?q=Search by title or transcript text.
POST/v1/meetings/:id/chatAsk a question of one meeting.

List meetings

GET /v1/meetings?limit=&offset=

Returns your most recent meetings, newest first. limit defaults to 50 (max 200).

Request

curl https://api.notabium.com/v1/meetings \
  -H "Authorization: Bearer ntb_live_..."

Response 200

{
  "meetings": [
    {
      "id": "6f1c2e8a-2b4d-4a1e-9c3f-7a0b1d2e3f44",
      "source": "extension_meet",
      "title": "Pricing sync with Acme",
      "platform": "google_meet",
      "status": "complete",
      "duration_s": 1840,
      "created_at": "2026-06-08T15:02:11.000Z",
      "completed_at": "2026-06-08T15:34:02.000Z"
    }
  ]
}

Get a meeting

GET /v1/meetings/:id

Returns the meeting row, its transcript (or null if not transcribed yet), and its outputs array. Outputs are the AI-generated artefacts; each has a kind of summary, next_steps, or email_draft. Returns 404 if the meeting does not exist or is not yours.

Request

curl https://api.notabium.com/v1/meetings/6f1c2e8a-2b4d-4a1e-9c3f-7a0b1d2e3f44 \
  -H "Authorization: Bearer ntb_live_..."

Response 200

{
  "meeting": {
    "id": "6f1c2e8a-2b4d-4a1e-9c3f-7a0b1d2e3f44",
    "title": "Pricing sync with Acme",
    "source": "extension_meet",
    "platform": "google_meet",
    "status": "complete",
    "duration_s": 1840,
    "lang": "en",
    "created_at": "2026-06-08T15:02:11.000Z",
    "completed_at": "2026-06-08T15:34:02.000Z"
  },
  "transcript": {
    "meeting_id": "6f1c2e8a-2b4d-4a1e-9c3f-7a0b1d2e3f44",
    "full_text": "Alex: Let's lock the pricing tiers before launch. Sam: Agreed, I think 19.99 holds...",
    "lang": "en"
  },
  "outputs": [
    {
      "kind": "summary",
      "content": "The team agreed to keep Pro at 19.99/mo and ship a 7-day trial..."
    },
    {
      "kind": "next_steps",
      "content": "1. Sam updates the pricing page. 2. Alex drafts the launch email..."
    },
    {
      "kind": "email_draft",
      "content": "Hi team, quick recap of today's pricing sync..."
    }
  ],
  "is_owner": true
}

Search meetings

GET /v1/meetings/search?q=...&limit=

Case-insensitive search over your meeting titles and transcript text. limit defaults to 20 (max 50). Each result includes a short snippet around the first match (transcript text where available, otherwise the title).

Request

curl "https://api.notabium.com/v1/meetings/search?q=pricing" \
  -H "Authorization: Bearer ntb_live_..."

Response 200

{
  "meetings": [
    {
      "id": "6f1c2e8a-2b4d-4a1e-9c3f-7a0b1d2e3f44",
      "title": "Pricing sync with Acme",
      "platform": "google_meet",
      "created_at": "2026-06-08T15:02:11.000Z",
      "duration_s": 1840,
      "snippet": "...lock the pricing tiers before launch. Sam: Agreed, I think 19.99 holds for Pro..."
    }
  ]
}

Ask a meeting

POST /v1/meetings/:id/chat

Ask a natural-language question; it is answered by the AI over that meeting's transcript. Send a JSON body with a message. The question and answer are saved to the meeting's chat thread, and the answer is returned. Returns 409 {"error":"no_transcript"} if the meeting has not been transcribed yet.

Request

curl https://api.notabium.com/v1/meetings/6f1c2e8a-2b4d-4a1e-9c3f-7a0b1d2e3f44/chat \
  -H "Authorization: Bearer ntb_live_..." \
  -H "Content-Type: application/json" \
  -d '{"message":"What did we decide about pricing?"}'

Response 200

{
  "message": {
    "id": "b2d4f6a8-1c3e-5a7b-9d0f-2e4a6c8b0d1f",
    "role": "assistant",
    "content": "You agreed to keep Pro at 19.99 per month and ship a 7-day free trial. Sam owns the pricing page update.",
    "created_at": "2026-06-09T09:14:30.000Z"
  }
}

Errors

Errors return a non-2xx status and a JSON body of the form {"error":"..."}. Common cases:

StatusBodyMeaning
401{"error":"unauthorized"}Missing, invalid, or revoked key.
403{"error":"forbidden"}The meeting is not yours.
403{"error":"session_required"}Endpoint needs a signed-in session, not a key.
404{"error":"not_found"}No such meeting.
409{"error":"no_transcript"}Meeting not transcribed yet (ask).
Prefer to let an assistant do the asking? Use the MCP server.
MCP guide Tutorials