Stock Library
Search Kolbo's unified multi-source stock media library (photos, videos, illustrations, vectors, 3D models, music, sound effects) and import assets into your media library.
The Stock Library is Kolbo's unified, multi-source catalog of ready-made media — photos, videos, illustrations, vectors, 3D models, music, and sound effects — aggregated behind one search. Use it to find b-roll, references, or project assets.
Library vs generation. These endpoints find existing assets and are free (no credits). To create new content, use image generation or video generation.
License. Your use of any asset is governed by the Asset Library License & Terms of Use. In short: Kolbo's own AI-generated music and sound effects are licensed for commercial use; third-party licensed assets (photos, videos, vectors, 3D) may be used only as original footage — not fed into AI generation/editing tools, and not used for AI training.
Sources today: Kolbo AI (kolbo-ai — our own AI-generated sound effects, music, and images), Pexels (photos, videos), Unsplash (photos), Pixabay (photos, illustrations, vectors, videos), Coverr (videos, music), Sketchfab (3D models), and Freesound (sound effects). Every route requires your X-API-Key.
The licensed production-music source (music) is not reachable through these endpoints. It is filtered out of /stock/sources and /stock/categories, and source=music returns 404 STOCK_NOT_FOUND on search, asset, and import. Use the Music Library endpoints for that catalog.
A source, or one of its media types, can be gated. Gated content is invisible rather than forbidden: the source is dropped from /stock/sources, /stock/categories returns an empty list, search returns an empty result set, and /stock/asset + /stock/import return 404 — never 403. If a source you expect is missing, that is why. Always read /stock/sources for the live list rather than hardcoding it.
Attribution. Every asset carries author, providerUrl, license, and a ready-to-render attribution string. When you display results you must credit the provider and the creator per their license.
Rate limits
| Routes | Limit |
|---|---|
sources, categories, collections, search, asset | 60 requests / minute / user |
analyze-script | 20 requests / minute / user |
import | 20 requests / minute / user |
Sources
List the enabled sources and which media types + filters each supports. Takes no parameters.
Endpoint
GET /api/v1/stock/sources{
"success": true,
"mediaTypes": ["image", "illustration", "vector", "video", "3d", "music", "sfx"],
"sources": [
{
"key": "kolbo-ai", "label": "Kolbo AI", "label_he": null,
"description": null, "description_he": null, "enabled": true,
"mediaTypes": ["sfx", "music", "image"],
"filters": {
"sfx": ["query","category","subcategory","collectionId","packId","lengthBucket","order"],
"music": ["query","genre","mood","theme","instrument","vocals","collectionId","order","bpmMin","bpmMax","durationMin","durationMax"],
"image": ["query","collectionId","packId","orientation","subject","setting","timeOfDay","copySpace","peopleCount","order"]
},
"attribution": null, "order_index": 0
},
{ "key": "pexels", "label": "Pexels", "mediaTypes": ["image", "video"], "filters": { "image": ["orientation","size","color","query"], "video": ["orientation","size","query"] }, "attribution": { "label": "Photos & videos provided by Pexels", "url": "https://www.pexels.com" } },
{ "key": "unsplash", "label": "Unsplash", "mediaTypes": ["image"], "filters": { "image": ["orientation","color","query"] } },
{ "key": "pixabay", "label": "Pixabay", "mediaTypes": ["image","illustration","vector","video"] },
{ "key": "coverr", "label": "Coverr", "mediaTypes": ["video","music"], "filters": { "video": ["category","orientation","order","query"], "music": ["order","query"] } },
{ "key": "sketchfab", "label": "Sketchfab", "mediaTypes": ["3d"], "filters": { "3d": ["query","category"] } },
{ "key": "freesound", "label": "Freesound", "mediaTypes": ["sfx"], "filters": { "sfx": ["query","order"] } }
]
}mediaTypes at the top level is the full set the library can expose; each source's own mediaTypes is what that source supports and what you are allowed to see. Only sources with enabled: true are returned, ordered by order_index.
A source's filters map lists what the provider supports, not what this API forwards. /stock/search currently forwards only the parameters in its own table below — theme, vocals, instrument, bpmMin / bpmMax, durationMin / durationMax, subject, setting, timeOfDay, copySpace, peopleCount, and Pexels size are advertised here but are not accepted as query parameters yet.
Categories
Dynamic category/topic chips per source. Pass the returned providerParam as the category filter on Search.
Endpoint
GET /api/v1/stock/categories?source=pixabay&mediaType=imageQuery Parameters
| Parameter | Type | Required | Constraints |
|---|---|---|---|
source | string | No | Restrict to one source key. Max 32 chars. Omit for every source. A gated or blocked source returns { categories: [], count: 0 }. |
mediaType | string | No | Restrict to one media type. Max 24 chars. Rows tagged mediaType: "all" match every type and are always included. |
{
"success": true,
"count": 20,
"categories": [
{
"source": "pixabay", "mediaType": "all", "key": "nature", "label": "Nature",
"label_he": null, "providerParam": "nature", "paramType": "category",
"thumbnailUrl": null, "order_index": 3, "group": null
}
]
}Rows come back sorted by source then order_index. paramType tells you which search parameter the row's providerParam belongs to (category or subcategory).
For Kolbo SFX (source=kolbo-ai&mediaType=sfx), categories are 2-level: top-level groups (group: null) and their sub-filters (each carries a group pointing to its parent, and paramType: "subcategory"). Pass a group's providerParam as category and a sub-filter's as subcategory.
Collections
Kolbo's own SFX library is organized into category collections (one per taxonomy group, kind: "category") and curated themed packs (kind: "pack" — e.g. Horror, Car Chase, In The Kitchen, Outer Space, Movie Trailer). Each has a cover image.
Endpoint
GET /api/v1/stock/collections?mediaType=sfx&kind=packQuery Parameters
| Parameter | Type | Required | Constraints |
|---|---|---|---|
mediaType | string | No | Default sfx. Only sfx returns anything — any other value returns an empty list. |
kind | string | No | category or pack. Any other value is ignored and both kinds are returned. |
This route only ever serves Kolbo's own (kolbo-ai) SFX collections — there is no source parameter. If kolbo-ai SFX is gated for your account you get { "collections": [], "count": 0 }.
{
"success": true,
"count": 12,
"collections": [
{
"id": "6a3c...", "slug": "sfx-col-horror", "title": "Horror", "title_he": null,
"description": null, "coverUrl": "https://media.kolbo.ai/...",
"kind": "pack", "categoryKey": null, "mediaType": "sfx", "order_index": 2
}
]
}Use a collection/pack id as packId or collectionId in Search to browse just that set.
Search
Unified search. With source=all (default) results from every provider that supports the media type are merged into one interleaved feed.
Endpoint
GET /api/v1/stock/searchQuery Parameters
| Parameter | Type | Required | Constraints |
|---|---|---|---|
query | string | No | Keyword search. For Kolbo AI sound effects, music and images a natural-language vibe works (semantic search) — see below. Omit to browse. Truncated to 200 chars (no error). A query written in a non-Latin script (Hebrew, Arabic, Cyrillic, Greek, CJK, Korean, Thai, Devanagari) is auto-translated to English first; Latin-script queries — including French, Spanish, German — are passed through verbatim. |
source | string | No | all (default), or a key from Sources: kolbo-ai, pexels, unsplash, pixabay, coverr, sketchfab, freesound. Truncated to 32 chars. music / synci → 404 STOCK_NOT_FOUND. An unknown key → 502 STOCK_ERROR. |
mediaType | string | No | image (default), illustration, vector, video, 3d, music, sfx. Anything else silently falls back to image. On a single-source search, a type the source does not support → 502 STOCK_ERROR. |
category | string | No | A providerParam from Categories. For Kolbo SFX these are the 77 Soundly-style groups (e.g. ambience, animals, vehicles, weapons, water, designed) and the match is exact and case-sensitive — send providerParam verbatim (they are lowercase slugs). Max 256 chars. |
subcategory | string | No | Kolbo SFX only. Sub-filter providerParam within a group (e.g. sword, splash, concrete, riser) — 623 sub-filters across the 77 groups. Same exact, case-sensitive match. Max 256 chars. |
packId | string | No | Kolbo AI only. Themed-pack id from Collections. Honoured for SFX on every path, and for AI images only on the keyword/browse path — an image search with a query runs semantic vibe search, which ignores packId. Kolbo AI music has collections but no packs. Must be a 24-char hex ObjectId: on SFX an invalid value is silently dropped, on images it makes the Kolbo source fail (502 STOCK_ERROR on a single-source search, or partial: true under source=all). Max 256 chars. |
collectionId | string | No | Kolbo AI only. Collection id from Collections. Honoured for music and images on every path, and for SFX only on the keyword/browse path — an SFX search with a query runs semantic vibe search, which ignores collectionId. Same 24-char hex ObjectId rule and same images-only failure mode as packId. Max 256 chars. |
genre | string | No | Kolbo AI music only. Exact match against the track's genre field (clipped to 64 chars server-side); it is not a substring or fuzzy match. Max 256 chars. |
mood | string | No | Kolbo AI music only. Exact match against one entry of the track's moods array (clipped to 64 chars server-side). Max 256 chars. |
lengthBucket | string | No | Kolbo SFX only. A bucket from the SFX taxonomy: oneshot, short, medium, long, loop, loopmax. Not validated — an unrecognized value simply matches nothing. Every SFX result echoes its own bucket as meta.lengthBucket, so read that rather than guessing. Max 256 chars. |
orientation | string | No | Unified vocabulary landscape / portrait / square. Pexels takes all three natively; Pixabay maps landscape→horizontal and portrait→vertical (it also accepts those two raw values, and has no square); Unsplash maps square→squarish and also accepts horizontal / vertical; Coverr post-filters landscape / portrait best-effort; Kolbo AI images match the stored enum exactly (landscape | portrait | square). Unrecognized values are dropped. |
color | string | No | Color filter. Pixabay: one or more comma-separated names from its own palette (unknown names are dropped, images/illustrations/vectors only). Pexels: a named or hex color (images only). Unsplash: a single named color, and only on an explicit query — it is ignored on a no-query browse. |
order | string | No | Sort order. popular / latest on Pixabay and Freesound; popular / latest / trending on Coverr; popular on Kolbo AI SFX and images (anything else = newest first). For Kolbo AI music: duration_asc, duration_desc, bpm_asc, bpm_desc, title, popular, newest — passing one of these disables semantic vibe ranking. On a mediaType=music multi-source feed, one of those seven values also re-sorts the whole merged page. Unrecognized values are dropped. |
cursor | string | No | Opaque pagination cursor, returned as nextCursor. Used by the cursor-paginated Sketchfab source: Sketchfab has no page numbers, so page > 1 without a cursor returns an empty Sketchfab result set. It also caps its own page at 24 regardless of perPage. Max 256 chars. |
page | number | No | 1-based page. Default 1, floored at 1. kolbo-ai hard-caps pagination depth at page 50. |
perPage | number | No | Results per page. Default 24, clamped to 1–80. |
Every filter value above is truncated to 256 characters; only string values are forwarded.
Browse is family-filtered, search is not. When query is empty the results pass through a family-friendly content filter (the unprompted browse feed stays clean). An explicit query returns exactly what you asked for, unfiltered.
curl "https://api.kolbo.ai/api/v1/stock/search?query=ocean%20waves&source=all&mediaType=video&perPage=4" \
-H "X-API-Key: kolbo_live_..."Semantic "vibe" search (Kolbo AI)
The kolbo-ai source is Kolbo's own AI-generated library: sound effects (mediaType=sfx), music (mediaType=music), and images (mediaType=image). For all three, a query is matched semantically — describe the feeling or use, not just keywords:
# Sound effects by vibe
curl "https://api.kolbo.ai/api/v1/stock/search?source=kolbo-ai&mediaType=sfx&query=tense%20ominous%20build-up%20for%20a%20horror%20reveal" \
-H "X-API-Key: kolbo_live_..."
# Music by vibe
curl "https://api.kolbo.ai/api/v1/stock/search?source=kolbo-ai&mediaType=music&query=uplifting%20hopeful%20corporate%20background" \
-H "X-API-Key: kolbo_live_..."
# Images by vibe
curl "https://api.kolbo.ai/api/v1/stock/search?source=kolbo-ai&mediaType=image&query=quiet%20minimal%20workspace%20with%20room%20for%20a%20headline" \
-H "X-API-Key: kolbo_live_..."Kolbo AI audio assets ship downloadVariants with per-file labels: SFX use mp3 and wav, music uses 320 (MP3), wav, and midi; images ship a single original. Each label appears only when that file exists for the asset, so read the labels rather than assuming — and pass one back as variant on Import. (External visual providers still want concrete keywords, not a vibe.)
Semantic ranking is the path taken only when there is a query. Because the vibe and keyword paths apply slightly different filters, packId (images) and collectionId (SFX) are honoured on the keyword/browse path but dropped once a query makes the search semantic — see their rows above. An explicit order on Kolbo AI music also turns semantic ranking off, since a deterministic sort and a relevance ranking cannot both win.
Response
{
"success": true,
"assets": [
{
"source": "pexels",
"sourceId": "12685044",
"mediaType": "video",
"title": "",
"thumbnailUrl": "https://images.pexels.com/videos/.../poster.jpeg",
"previewUrl": "https://images.pexels.com/videos/.../poster.jpeg",
"width": 3840, "height": 2160, "durationSeconds": 20,
"downloadVariants": [
{ "label": "uhd-2160p", "url": "https://...", "width": 3840, "height": 2160, "ext": "mp4", "fileSizeBytes": 12345678 }
],
"author": { "name": "CityXcape", "url": "https://www.pexels.com/@cityxcape" },
"providerUrl": "https://www.pexels.com/video/...",
"license": { "name": "Pexels License", "attributionRequired": false, "url": "https://www.pexels.com/license/" },
"tags": [],
"attribution": "Video by CityXcape on Pexels"
}
],
"page": 1, "perPage": 4, "total": 8500, "hasMore": true, "partial": false, "nextCursor": null,
"sources": [ { "source": "pexels", "total": 8000, "hasMore": true, "nextCursor": null }, { "source": "pixabay", "total": 500, "hasMore": true, "nextCursor": null } ]
}Paginate by incrementing page (the same page is requested from each provider, so the interleaved feed stays consistent).
total is the sum across providers; a per-source sources[].total can be null when that provider does not report one. partial: true and a sources[].error: true entry mean one provider failed and the feed is incomplete — distinct from a genuinely empty result, and worth retrying. partial is only returned on the source=all fan-out; a single-source search omits it. nextCursor appears when a cursor-paginated provider (Sketchfab) participated; pass it back as cursor.
Asset
Resolve a single normalized asset with all download variants.
Endpoint
GET /api/v1/stock/asset/:source/:id| Parameter | Type | Required | Constraints |
|---|---|---|---|
:source | string | Yes | kolbo-ai, pexels, unsplash, pixabay, coverr, sketchfab, or freesound. music / synci → 404 STOCK_NOT_FOUND; an unknown key → 502 STOCK_ERROR. |
:id | string | Yes | The provider asset id (sourceId). |
mediaType | string (query) | No | Media type hint (e.g. video) for sources that reuse ids across types. Truncated to 24 chars. |
curl "https://api.kolbo.ai/api/v1/stock/asset/pexels/12685044?mediaType=video" \
-H "X-API-Key: kolbo_live_..."Returns { "success": true, "asset": { ... } } with the same asset shape as Search. An unresolvable id returns 404 STOCK_NOT_FOUND.
Analyze Script (auto b-roll)
AI helper that turns a video/voiceover script into concrete stock b-roll search terms you can feed into Search.
Endpoint
POST /api/v1/stock/analyze-scriptRequest Body
| Parameter | Type | Required | Constraints |
|---|---|---|---|
script | string | Yes | The script / scene description. Trimmed; empty → 400. Clipped server-side to the first 8000 characters. |
curl -X POST https://api.kolbo.ai/api/v1/stock/analyze-script \
-H "X-API-Key: kolbo_live_..." \
-H "Content-Type: application/json" \
-d '{ "script": "Aerial shots of a coastal city at sunrise, then a team collaborating in a modern office." }'{
"success": true,
"queries": ["coastal city sunrise", "aerial drone ocean", "team collaborating office", "modern office interior"],
"mediaType": "video",
"keywords": ["coast", "sunrise", "drone", "office", "teamwork"]
}queries holds up to 6 concrete visual phrases (the model is asked for 3–6; only "at least one" is enforced, each clipped to 60 chars), mediaType is "video" or "image" (anything else becomes "image"), and keywords holds up to 6 tags. If no query at all can be derived you get 422 with code STOCK_SCRIPT_EMPTY.
Import
Copy a stock asset into your media library — downloaded to Kolbo's CDN with a stable URL so it can be used in projects and generations. Free. The licensed music source is not importable here — use Import Track to Media Library for it.
Endpoint
POST /api/v1/stock/importRequest Body
| Parameter | Type | Required | Constraints |
|---|---|---|---|
source | string | Yes | kolbo-ai, pexels, unsplash, pixabay, coverr, freesound, or sketchfab. music / synci → 404 STOCK_NOT_FOUND; an unknown key → 400 STOCK_UNKNOWN_SOURCE. |
id | string | Yes | The provider asset id. sketchfab takes its own path: the id must be a 32-character hex uid (400 STOCK_INVALID_ID), the model must be downloadable (400 STOCK_NOT_DOWNLOADABLE) and available as GLB (400 STOCK_NOT_GLB), and variant / mediaType are ignored. |
mediaType | string | No | Media type hint (e.g. video, vector). Needed for sources that reuse ids across types. |
variant | string | No | Which download variant label to import (from Asset). An unknown label falls back to the first variant; an asset with no variants → 400 STOCK_NO_DOWNLOAD. |
project_id | string | No | Project to file the item under. projectId is accepted as an alias. |
curl -X POST https://api.kolbo.ai/api/v1/stock/import \
-H "X-API-Key: kolbo_live_..." \
-H "Content-Type: application/json" \
-d '{ "source": "pexels", "id": "12685044", "mediaType": "video" }'{
"success": true,
"alreadyImported": false,
"libraryItem": { "_id": "...", "mediaType": "video", "url": "https://media.kolbo.ai/...", "filename": "..." }
}Re-importing the same (source, id) returns the existing item with alreadyImported: true — dedup is per user, and nothing is re-downloaded. The created item is sourceType: "stock" with metadata.stockSource, metadata.stockSourceId, metadata.variant, and the author/license/attribution copied onto it, so it stays separate from your own uploads in the Media Library.
Typical Flow
- From a script →
POST /stock/analyze-scriptto getqueries[]+mediaType. - Search →
GET /stock/searchfor each query (source=all). ShowthumbnailUrl+attribution. - Resolve →
GET /stock/asset/:source/:idfor the full download variants. - Use it →
POST /stock/importto copy the asset into the media library (stable CDN URL), then reference it in a project or generation.
Notes
- All Stock Library endpoints are free — they do not consume credits.
- Always display the provider + creator credit (
attribution) when you show results. - Pixabay vectors currently ship as a high-resolution raster (true SVG requires Pixabay full API access);
meta.vectorRasterOnlyflags these.
Errors
All errors return { "success": false, "error": "...", "code": "..." }.
| Code | Status | Meaning |
|---|---|---|
STOCK_NOT_FOUND | 404 | Asset does not exist, or the source / media type is gated or blocked for you. Also returned for source=music / source=synci on search, asset and import. |
STOCK_UNKNOWN_SOURCE | 400 | No such source key — import only. On /stock/search and /stock/asset the same condition surfaces as 502 STOCK_ERROR. |
STOCK_NO_DOWNLOAD | 400 | The asset has no downloadable file (import). |
STOCK_INVALID_ID | 400 | Malformed provider id (3D imports require a 32-char hex uid). |
STOCK_NOT_DOWNLOADABLE | 400 | The Sketchfab model is not available for download. |
STOCK_NOT_GLB | 400 | The Sketchfab model has no GLB build. |
STOCK_TOO_LARGE | 400 | The asset exceeds the per-media-type import size cap: 350 MB for video, 150 MB for music, 60 MB for everything else (image, illustration, vector, sfx). Pick a smaller variant and retry. |
STOCK_UNTRUSTED_HOST | 400 | The resolved download URL is not on the provider's allow-list. |
STOCK_SOURCE_UNAVAILABLE | 503 | The 3D source is not configured on this environment (Sketchfab import). On /stock/search the same condition — a single source that is registered but has no credentials configured — surfaces as 502 STOCK_ERROR instead. |
STOCK_SCRIPT_EMPTY | 422 | analyze-script could not derive any b-roll query. |
STOCK_SCRIPT_ERROR | 502 | analyze-script failed. |
STOCK_ERROR | 502 | Any other failure, including an unknown source, a registered-but-unconfigured source, or an unsupported single-source mediaType on search / asset. |
Related
Music Library
The licensed production-music catalog, stems, and clean-master acquisition
Media Library
Where imported assets land, and how to list, folder, and reuse them
Asset Library License
The license and terms governing every asset you obtain here
Video Generation
Turn an imported still into motion, or generate new footage instead
Music Library
Search Kolbo's licensed production-music catalog, resolve preview URLs, and acquire clean, unwatermarked masters.
Asset Library License & Terms of Use
The license and terms of use governing assets (AI-generated music and SFX, and third-party licensed photos, videos, vectors, and 3D models) obtained from the Kolbo.AI Asset Library.