Developer docs
REST API
The Notul.ai API lets you upload recordings and retrieve meeting notes programmatically. Useful for automating your workflow or integrating with internal tooling.
Authentication
All API requests require an X-API-Key header. You can create API keys in Settings under the API Keys section.
Keys start with ntl_ and are only shown once on creation. Store them securely.
X-API-Key: ntl_your_api_key_hereRequests without a valid key return 401 Unauthorized.
Base URL
https://notul.ai/v1Endpoints
/v1/meetingsReturns a list of all your meetings, ordered by creation date (newest first).
Request
curl https://notul.ai/v1/meetings \
-H "X-API-Key: ntl_your_api_key_here"Response
[
{
"id": 42,
"title": "Wekelijks overleg",
"status": "done",
"created_at": "2026-07-21T10:30:00Z",
"calendar_start": "2026-07-21T10:00:00Z",
"calendar_end": "2026-07-21T11:00:00Z",
"calendar_attendees": ["alice@example.com", "bob@example.com"],
"detected_language": "nl"
}
]/v1/meetings/{id}Returns a single meeting including the generated notes.
Request
curl https://notul.ai/v1/meetings/42 \
-H "X-API-Key: ntl_your_api_key_here"Response
{
"id": 42,
"title": "Wekelijks overleg",
"status": "done",
"created_at": "2026-07-21T10:30:00Z",
"calendar_start": "2026-07-21T10:00:00Z",
"calendar_end": "2026-07-21T11:00:00Z",
"calendar_attendees": ["alice@example.com", "bob@example.com"],
"detected_language": "nl",
"notes_text": "## Actiepunten\n\n- Alice stuurt het rapport..."
}/v1/meetingsUpload an audio or video recording. The file is transcribed and notes are generated automatically. Accepted formats: mp3, mp4, m4a, wav, ogg, webm, flac. Maximum file size depends on your plan (Starter: 500 MB, Pro: 2 GB).
Request
curl -X POST https://notul.ai/v1/meetings \
-H "X-API-Key: ntl_your_api_key_here" \
-F "file=@recording.mp3"Response
{
"id": 43,
"title": "recording.mp3",
"status": "pending",
"created_at": "2026-07-21T14:00:00Z",
"detected_language": null
}Meeting status
After uploading, a meeting goes through several statuses. Poll GET /v1/meetings/{id} until status is done or failed.
| Status | Description |
|---|---|
pending | Waiting to be picked up for transcription |
transcribing | Audio is being transcribed |
transcribed | Transcript ready, notes generation queued |
generating_notes | Notes are being generated from the transcript |
done | Notes are ready in notes_text |
failed | Processing failed |
Error responses
Errors are returned as JSON with a code field.
{
"error": {
"code": "invalid_api_key",
"message": "Invalid or missing API key"
}
}| HTTP status | Code | When |
|---|---|---|
| 401 | invalid_api_key | Key is missing or not recognised |
| 403 | forbidden | Key is valid but quota is exceeded |
| 404 | not_found | Meeting does not exist or belongs to another account |
| 422 | file_required | No file was included in the upload |
| 500 | internal | Unexpected server error |
Rate limits
The API is rate-limited to 60 requests per minute per API key. Exceeding this limit returns 429 Too Many Requests.