API reference
Wire BrollCollective into anything.
Three endpoints, one bearer token. Search the vault, pull clip metadata, and issue signed CDN URLs. Everything our own product uses, available over HTTPS.
Authentication
Bearer tokens
Every request passes your API key as a bearer token. Keys start with brc_live_ in production and brc_test_ in the review sandbox. Generate one at Settings → API keys.
curl -H "Authorization: Bearer brc_live_…" \
https://brollcollective.com/api/v1/vault/search?q=golden+hour&pageSize=5/api/v1/vault/searchscope: read:vaultSearch the vault
Paginated, filterable search across every published clip. Mirrors the in-app vault filters (audience, city, orientation, mood, free-text query) and returns a cursor for keyset pagination.
| q | string | Free-text query. When Meilisearch is live it ranks by relevance; otherwise falls back to pg_trgm similarity. |
| audience | enum | `real_estate` · `restaurant` · `creator` · `all`. Defaults to `all`. |
| city | string | City slug, e.g. `seattle-wa`. Combine with `radiusKm` to widen. |
| radiusKm | integer | Search radius around the city centroid in kilometers (1-500). |
| orientation | enum | `vertical` · `horizontal` · `any`. Defaults to `any`. |
| mood | string | Match one of the moods returned by `availableMoods`. |
| promptNumber | integer | Filter to clips shot for a specific prompt (1-50). |
| sort | enum | `recent` · `popular` · `quality`. |
| pageSize | integer | Items per page, 1-100 (default 24). |
| cursor | string | Opaque keyset cursor from the previous response's `cursor` field. |
Request
curl -G "https://brollcollective.com/api/v1/vault/search" \
-H "Authorization: Bearer brc_live_…" \
--data-urlencode "q=golden hour" \
--data-urlencode "city=seattle-wa" \
--data-urlencode "pageSize=10"200 OK response
{
"object": "list",
"mode": "live",
"total": 412,
"has_more": true,
"cursor": "eyJwIjoxLCJrIjoiYzE4MiJ9",
"data": [
{
"id": "c12f4a0e-…",
"title": "Capitol Hill golden hour pan",
"audience": "real_estate",
"orientation": "horizontal",
"duration_seconds": 14,
"city": "Seattle",
"region": "WA",
"city_slug": "seattle-wa",
"centroid": { "lat": 47.622, "lng": -122.318 },
"uploader_handle": "pnw_aerial",
"prompt_number": 12,
"downloads": 184,
"quality_score": 0.92,
"tags": ["golden-hour","rooftop","skyline"],
"moods": ["warm","cinematic"],
"published_at": "2026-03-22T19:04:00Z",
"preview_url": "https://cdn.brollcollective.com/…",
"links": {
"detail": "/api/v1/vault/c12f4a0e-…",
"download": "/api/v1/vault/c12f4a0e-…/download"
}
}
],
"availableMoods": ["warm","cinematic","moody","bright"]
}/api/v1/vault/{id}scope: read:vaultGet a single clip
Single-clip metadata with the full rendition ladder (4k / 1080p / 720p / 9:16) and any AI-enriched fields (scene description, quality score, best use cases).
Request
curl -H "Authorization: Bearer brc_live_…" \
https://brollcollective.com/api/v1/vault/c12f4a0e-…200 OK response
{
"object": "clip",
"id": "c12f4a0e-…",
"title": "Capitol Hill golden hour pan",
"description": "Slow pan over the skyline as the sun clears the Cascades.",
"status": "published",
"orientation": "horizontal",
"duration_seconds": 14,
"ai": {
"scene_description": "Rooftop view of downtown Seattle with warm backlight.",
"quality_score": 0.92,
"best_use_cases": ["real_estate_reel","city_b_roll"]
},
"published_at": "2026-03-22T19:04:00Z",
"assets": [
{ "label": "4k", "cdn_url": "https://cdn.…/c12f4a0e/4k.mp4", "width": 3840, "height": 2160 },
{ "label": "1080p", "cdn_url": "https://cdn.…/c12f4a0e/1080p.mp4", "width": 1920, "height": 1080 },
{ "label": "9x16", "cdn_url": "https://cdn.…/c12f4a0e/9x16.mp4", "width": 1080, "height": 1920 }
]
}/api/v1/vault/{id}/downloadscope: download:vaultIssue a signed download URL
Returns a 15-minute presigned URL for the requested rendition. Each call increments the key owner's `api_calls_overage` meter and, when billing is wired, counts against your plan's included downloads.
| rendition | enum | `4k` · `1080p` · `720p` · `9x16`. Defaults to `1080p`. |
Request
curl -X POST "https://brollcollective.com/api/v1/vault/c12f4a0e-…/download" \
-H "Authorization: Bearer brc_live_…" \
-H "content-type: application/json" \
-d '{"rendition":"4k"}'200 OK response
{
"object": "download_url",
"video_id": "c12f4a0e-…",
"rendition": "1080p",
"url": "https://cdn.brollcollective.com/…?X-Amz-Signature=…",
"expires_in_seconds": 900,
"key_id": "apk_3m0h…"
}Rate limits
Per-key sliding window
Every response includes X-RateLimit-Remaining and X-RateLimit-Reset headers. 429s carry a Retry-After value in seconds.
Errors
Standard JSON envelope
Every error is a JSON object with a stable error code plus a human-readable hint. Never parse the HTTP status alone.
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Malformed or missing required parameters. |
| 401 | unauthorized | Missing, malformed, or revoked API key. |
| 403 | forbidden | Key lacks the scope listed under `required_scope`. |
| 404 | not_found | Clip id doesn't exist or isn't published. |
| 429 | rate_limited | Hit a per-key rate-limit window. |
| 500 | server_error | Something we need to look at. Retry with backoff. |
Scopes
Key scopes
Search + read clip metadata. Safe to ship in client-side code with a short-lived key.
Issue signed CDN URLs. Keep this on a server-side key. Leaking it costs you real $.
Changelog
v1 timeline
Public API docs
Launched /docs/api with curl + Node + Python samples for every endpoint.
download:vault
Added POST /vault/{id}/download for short-lived signed URLs.
v1 public preview
GET /vault/search and /vault/{id} opened to key holders.