API reference
Early access. Capvo is rolling out gradually. API access is enabled for early-access accounts as they come onboard — join the waitlist to get yours.
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.
Every key is limited to 100 requests per minute, on every plan. 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 | The next_cursor value returned by the previous page. |
platform | string | Filter: meet, zoom, teams, phone. |
created_after | datetime | ISO 8601. Inclusive lower bound on created_at. |
created_before | datetime | ISO 8601. Inclusive 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,
"started_at": "2026-04-27T14:02:11Z",
"ended_at": "2026-04-27T14:32:53Z",
"status": "ready",
"transcript": [
{ "sequence": 1, "speaker": "Albert", "content": "Let's start with the numbers.", "start_time": 4.2, "end_time": 8.9 },
{ "sequence": 2, "speaker": "Maya", "content": "Revenue is up 18% quarter over quarter.", "start_time": 9.1, "end_time": 13.4 }
],
"summary": {
"context": "Quarterly revenue review with finance.",
"decisions": ["Ship the updated forecast this week"],
"action_items": [{ "task": "Send updated forecast to finance", "owner": "Albert", "deadline": null }],
"participants": ["Albert", "Maya"],
"next_step": "Forecast review on Friday",
"budget_mentioned": null,
"sentiment": "positive"
}
}
],
"next_cursor": "2026-04-27T14:02:11Z",
"has_more": true
}Each note id is a UUID v4. The transcript array is included inline; there is no
separate transcript_url. summary is null until the AI summary has been
generated for that meeting.
TypeScript
interface NotesListResponse {
data: Note[]
next_cursor: string | null
has_more: boolean
}
interface Note {
id: string // UUID v4
title: string | null
platform: 'meet' | 'zoom' | 'teams' | 'phone'
duration_seconds: number
started_at: string
ended_at: string
status: string
transcript: TranscriptSegment[]
summary: Summary | null
}
interface TranscriptSegment {
sequence: number // 1-indexed segment order
speaker: string
content: string
start_time: number // seconds from start of recording
end_time: number | null
}
interface Summary {
context: string | null
decisions: string[]
action_items: Array<{ task: string; owner: string | null; deadline: string | null }>
participants: string[]
next_step: string | null
budget_mentioned: string | null
sentiment: string | null
}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"The response is a single Note object — the same shape as the entries in
List notes. A note that does not exist (or belongs to another
account) returns 404.
To delete a meeting and its transcript, use the desktop app (the meeting's ⋯ menu → Delete). Deletion via the API is not available yet.
Search notes
Semantic search across the meetings you own. The query is embedded and matched against meeting summaries by similarity, so it finds meaning, not just keywords.
GET /v1/notes/search?q=...Parameters
| Parameter | Type | Description |
|---|---|---|
q | string | Required. The natural-language search query. |
limit | integer | Max results, default 5, max 20. |
Example
curl "https://api.capvo.app/v1/notes/search?q=budget+approval" \
-H "Authorization: Bearer cpv_your_key"{
"data": [
{
"id": "fd1c2b0e-08a2-4ee0-ab26-9f3a7a14b2c1",
"title": "Q2 Revenue Review",
"platform": "meet",
"duration_seconds": 1842,
"started_at": "2026-04-27T14:02:11Z",
"ended_at": "2026-04-27T14:32:53Z",
"status": "ready",
"transcript": [
{ "sequence": 1, "speaker": "Albert", "content": "Let's start with the numbers.", "start_time": 4.2, "end_time": 8.9 }
],
"summary": null
}
]
}Results are full Note objects, ranked by relevance, transcript included — no
second request needed.
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"],
"active": true,
"created_at": "2026-04-27T14:02:11Z",
"secret": "8f3a1c9e2b7d4f6a0c5e8b1d3f7a2c4e6b9d1f3a5c7e0b2d4f6a8c1e3b5d7f9a"
}The endpoint id is a UUID v4. events defaults to ["meeting.completed"] when
omitted. The endpoint URL must be https:// and publicly reachable — addresses
that resolve to private networks are rejected.
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 and returns { "success": true }.
Delivery history
GET /v1/webhooks/:id/deliveriesPaginated log of every delivery attempt to an endpoint (newest first), including the event name, HTTP status code your endpoint returned, the attempt number, and the payload. Use it to debug failed deliveries without leaving your terminal.
| Parameter | Type | Description |
|---|---|---|
limit | integer | Max results, default 25, max 100. |
cursor | string | The next_cursor value from the previous page. |
Error codes
All errors return a JSON body with an error message:
{
"error": "Note not found"
}| HTTP | Meaning |
|---|---|
| 400 | Required parameters are missing or malformed. |
| 401 | The API key is missing, invalid, or revoked. |
| 404 | The resource does not exist or is not visible to your key. |
| 429 | You have exceeded the rate limit (100 req/min). Honor Retry-After. |
| 500 | Something broke on our side. The request can be safely retried. |