API
Create capture requests and recording sessions, get told when a recording lands, and download the original file with a record of how it was made.
The API is included with Team and Platform. Keys are created at capturly.app/account/api-keys .
The thing to understand first
Capture is local, so it is asynchronous. When a session ends the media is still on someone’s laptop, and it may never arrive. That is the shape of the API, not an edge case to code around.
Three consequences:
- Tracks arrive independently, over minutes to hours. A recording with two of four tracks present is a correct response, not a partial failure.
- A take can strand when a client vanishes mid-upload. That is a real state with a recovery path, not an error.
- Polling has no bounded answer. Subscribe to webhooks rather than asking repeatedly whether a recording is ready.
Authentication
A bearer token on every request:
curl https://capturly.app/api/v1/recordings \
-H "Authorization: Bearer cap_live_..."Keys are organization-scoped and shown once at creation. They survive the member who created them leaving, because they belong to the organization rather than to a person.
Cookies are not accepted. A browser session here would make every endpoint reachable from any page a user has open.
Live and test keys
A cap_test_ key authenticates and reads, but is refused anything with an
effect outside Capturly that cannot be taken back: minting a download URL,
mailing a real person, or opening a session that draws on your allowance.
Reads are unrestricted, so a test key exercises every response shape.
Test keys have no fixture data behind them. They read your organization, which for a new one is empty.
Scopes
A key grants exactly what you check, and nothing implies anything else — reading a recording is not permission to download it.
| Scope | Grants |
|---|---|
recordings:read | List recordings and read capture manifests |
recordings:download | Mint short-lived download URLs |
usage:read | Read capture usage |
capture_requests:read | List capture requests, rosters and submitted takes |
capture_requests:write | Create, edit and close requests; add contacts |
sessions:read | List sessions and see who joined |
sessions:write | Create sessions, mint invites, end them |
Errors
| Status | Meaning |
|---|---|
401 unauthorized | No key, or one that does not authenticate. Identical for unknown, revoked and expired keys. |
403 insufficient_scope | The key is missing a scope. The response names it. |
403 test_mode_scope | A test key attempted something live-only. |
403 plan_inactive | The organization’s plan no longer includes API access. |
403 upgrade_required | The plan does not include this feature. The response names the plan that does. |
402 capture_allowance_reached | The capture allowance is spent. Recording continues; new capture requests wait. |
409 organization_paused | The organization’s plan has lapsed, so respondent links would not resolve. |
409 capture_request_closed | The capture request is closed and takes no more contacts or takes. |
429 contact_cap | The roster is at its ceiling. The response carries the cap and the current count. |
429 rate_limited | Over the per-key budget above. Worth retrying after a pause. |
400 invalid_input | The body failed validation. The response names the field. |
400 invalid_cursor | A pagination cursor that resolves to nothing. |
404 not_found | No such object, or one belonging to another organization. |
The 401 is deliberately uniform. Distinguishing a revoked key from an unknown one would let a caller probe which keys exist.
Pagination
List endpoints are cursor-paginated, newest first:
curl "https://capturly.app/api/v1/recordings?limit=25&cursor=rec_abc" \
-H "Authorization: Bearer cap_live_..."nextCursor is null on the last page, never absent, so you can branch on the
field without distinguishing “missing” from “no more”.
A cursor that no longer resolves returns 400 invalid_cursor rather than an
empty page. To a syncing client an empty page reads as “walk complete”, which
would turn an aged-out cursor into silent data loss.
Rate limits
Per key, per minute:
| Requests | Budget |
|---|---|
| Reads | 600 |
| Writes — anything that creates, edits, closes or deletes | 60 |
| Download-URL minting, which signs a URL each time | 60 |
Limits key on the credential rather than the caller’s address, so a leaked key
stays bounded across every host running it. Over budget answers
429 rate_limited.