API reference
The Capvo REST API lets you read your transcripts, search across meetings, and manage webhook endpoints. Base URL:
https://api.capvo.appAll requests require an API key. All responses are JSON. All timestamps are ISO 8601 in UTC.
Authentication
Send your API key as a Bearer token in the Authorization header.
curl https://api.capvo.app/v1/notes \
-H "Authorization: Bearer cpv_your_key"API keys are scoped to your account. They're stored bcrypt-hashed on the server, so we never have access to the plaintext after creation. Lost keys cannot be recovered; revoke and create a new one.
Rate limits depend on your plan:
| Plan | Requests / day |
|---|---|
| Free | 100 |
| Pro | 10,000 |
| Enterprise | Custom |
When rate-limited you receive 429 Too Many Requests with a Retry-After header.
List notes
Returns a paginated list of your recorded meetings, newest first.
GET /v1/notesParameters
| Parameter | Type | Description |
|---|---|---|
limit | integer | Max results, default 20, max 100. |
cursor | string | Opaque cursor returned by the previous page. |
platform | string | Filter: meet, zoom, teams, phone, microphone. |
created_after | datetime | ISO 8601. Inclusive lower bound on created_at. |
created_before | datetime | ISO 8601. Exclusive upper bound on created_at. |
Example
curl "https://api.capvo.app/v1/notes?limit=20&platform=meet" \
-H "Authorization: Bearer cpv_your_key"{
"data": [
{
"id": "fd1c2b0e-08a2-4ee0-ab26-9f3a7a14b2c1",
"title": "Q2 Revenue Review",
"platform": "meet",
"duration_seconds": 1842,
"created_at": "2026-04-27T14:02:11Z",
"ended_at": "2026-04-27T14:32:53Z",
"transcript": [
{ "speaker": "Albert", "sequence": 1, "start_time": 4.2, "content": "Let's start with the numbers." },
{ "speaker": "Maya", "sequence": 2, "start_time": 9.1, "content": "Revenue is up 18% quarter over quarter." }
]
}
],
"next_cursor": "eyJpZCI6ImZkMWMyYjBlIn0",
"has_more": true
}Each note id is a UUID v4. The transcript array is included inline. There is no
separate transcript_url.
TypeScript
interface NotesListResponse {
data: NoteSummary[]
next_cursor: string | null
has_more: boolean
}
interface NoteSummary {
id: string // UUID v4
title: string
platform: 'meet' | 'zoom' | 'teams' | 'phone' | 'microphone'
duration_seconds: number
created_at: string
ended_at: string
transcript: TranscriptSegment[]
}
interface TranscriptSegment {
speaker: string
sequence: number // 1-indexed segment order
start_time: number // seconds from start of recording
content: string
}Get a note
Returns a single meeting with its full transcript.
GET /v1/notes/:idExample
curl https://api.capvo.app/v1/notes/fd1c2b0e-08a2-4ee0-ab26-9f3a7a14b2c1 \
-H "Authorization: Bearer cpv_your_key"{
"id": "fd1c2b0e-08a2-4ee0-ab26-9f3a7a14b2c1",
"title": "Q2 Revenue Review",
"platform": "meet",
"duration_seconds": 1842,
"created_at": "2026-04-27T14:02:11Z",
"ended_at": "2026-04-27T14:32:53Z",
"language": "en",
"transcript": [
{ "speaker": "Albert", "sequence": 1, "start_time": 4.2, "content": "Let's start with the numbers." },
{ "speaker": "Maya", "sequence": 2, "start_time": 9.1, "content": "Revenue is up 18% quarter over quarter." }
],
"summary": null,
"action_items": [
{ "text": "Send updated forecast to finance", "assignee": "Albert" }
]
}TypeScript
interface Note {
id: string // UUID v4
title: string
platform: 'meet' | 'zoom' | 'teams' | 'phone' | 'microphone'
duration_seconds: number
created_at: string
ended_at: string
language: string
transcript: TranscriptSegment[]
summary: string | null
action_items: ActionItem[]
}
interface TranscriptSegment {
speaker: string
sequence: number // 1-indexed segment order
start_time: number // seconds from start of recording
content: string
}
interface ActionItem {
text: string
assignee: string | null
}Delete a note
Permanently deletes a meeting, its transcript, embeddings, and any cached audio. The deletion propagates to underlying storage within 24 hours.
DELETE /v1/notes/:idExample
curl -X DELETE https://api.capvo.app/v1/notes/fd1c2b0e-08a2-4ee0-ab26-9f3a7a14b2c1 \
-H "Authorization: Bearer cpv_your_key"A successful delete returns 204 No Content. Calling delete on a note that has
already been deleted returns 404 not_found.
Search notes
Semantic search across the transcripts you own. Results are ranked by embedding similarity to the query.
GET /v1/notes/search?q=...Parameters
| Parameter | Type | Description |
|---|---|---|
q | string | Required. The search query (max 256 characters). |
limit | integer | Max results, default 10, max 50. |
Example
curl "https://api.capvo.app/v1/notes/search?q=budget+approval" \
-H "Authorization: Bearer cpv_your_key"{
"data": [
{
"note_id": "fd1c2b0e-08a2-4ee0-ab26-9f3a7a14b2c1",
"title": "Q2 Revenue Review",
"snippet": "…we'll need budget approval from finance before…",
"score": 0.84,
"start_time": 612.4
}
]
}The start_time is seconds from the start of the recording, pointing to the segment
that matched the query. Use it to deep-link straight to that moment in the
transcript.
Manage webhooks
Webhook endpoints can be created from the desktop app or via the API.
Create endpoint
POST /v1/webhookscurl https://api.capvo.app/v1/webhooks \
-H "Authorization: Bearer cpv_your_key" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/capvo",
"events": ["meeting.transcribed", "summary.ready"]
}'{
"id": "b7a9c4d2-1f3e-4a8b-9c5d-6e2f8a3b1c4d",
"url": "https://example.com/capvo",
"events": ["meeting.transcribed", "summary.ready"],
"secret": "whsec_8y2pMabc...",
"created_at": "2026-04-27T14:02:11Z",
"active": true
}The endpoint id is a UUID v4. The secret keeps the whsec_ prefix so it's easy
to recognise in your secret manager.
The secret is shown once. Use it to verify the HMAC signature on incoming webhooks.
See HMAC verification.
List endpoints
GET /v1/webhooksReturns all active and inactive webhook endpoints for your account. Secrets are not returned; you receive them only when an endpoint is created.
Delete an endpoint
DELETE /v1/webhooks/:idRemoves the endpoint immediately. In-flight retries are cancelled.
Error codes
All errors return a JSON body with an error object:
{
"error": {
"code": "invalid_api_key",
"message": "The API key you provided is invalid or has been revoked."
}
}| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Required parameters are missing or malformed. |
| 401 | invalid_api_key | The API key is missing, invalid, or revoked. |
| 403 | forbidden | The key is valid but does not have access to this resource. |
| 404 | not_found | The resource does not exist or is not visible to your key. |
| 409 | conflict | The resource already exists or is in a conflicting state. |
| 422 | validation_error | The request was well-formed but semantically invalid. |
| 429 | rate_limited | You have exceeded the rate limit. Honor the Retry-After. |
| 500 | internal_error | Something broke on our side. The request can be safely retried. |
| 503 | service_unavailable | The API is temporarily unavailable. Retry with backoff. |