Uploads

Register a recording made elsewhere

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.

posthttps://api-notetaker.nabrah.ai/ext/v1/uploads

Body

titlestring
filenamestringrequired
contentTypestring
byteSizeinteger
startsAtstring · date-time
kindenum
audiotranscript

Request

curl -X POST https://api-notetaker.nabrah.ai/ext/v1/uploads \
  -H "Authorization: Bearer $NABRAH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "string",
  "filename": "string",
  "contentType": "string",
  "byteSize": 0,
  "startsAt": "2026-01-01T09:00:00.000Z",
  "kind": "audio"
}'

Responses

201One upload.
401No key, an unknown key, or one that has been revoked or has expired.
403The key is read only, or lacks the reach for this route.
404No such record — or one that belongs to another account.
409Refused, 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.
422The body or query failed validation; details names the field.
429Too many requests. Retry-After says how long to wait.
{
  "data": {
    "id": "00000000-0000-0000-0000-000000000000",
    "runId": "00000000-0000-0000-0000-000000000000",
    "reference": "string",
    "title": "string",
    "kind": "audio",
    "stage": "pending",
    "filename": "string",
    "byteSize": 0,
    "durationMs": 0,
    "startsAt": "2026-01-01T09:00:00.000Z",
    "createdAt": "2026-01-01T09:00:00.000Z",
    "updatedAt": "2026-01-01T09:00:00.000Z",
    "error": "string",
    "hasNotes": true,
    "usage": {
      "remaining": 0,
      "maxMinutes": 0,
      "resetsAt": "2026-01-01T09:00:00.000Z"
    }
  }
}