Media search
Search a stock library of photos and videos, browse curated photos and popular videos, or fetch a
single item by id. Every call is a GET and goes through the same authentication, rate-limit
and quota pipeline as every other service.
| Method & path | Returns |
|---|---|
GET /api/v1/media/photos/search | Photos matching query |
GET /api/v1/media/photos/curated | A curated selection of photos |
GET /api/v1/media/photos/{id} | One photo |
GET /api/v1/media/videos/search | Videos matching query |
GET /api/v1/media/videos/popular | Popular videos |
GET /api/v1/media/videos/{id} | One video |
Parameters
Query-string parameters for the four list routes. Anything outside these rules returns
400 bad_request.
| Parameter | Default | Notes |
|---|---|---|
query | — | Required on the two search routes. Up to 200 characters. |
per_page | 15 | Items per page, 1–50. |
page | 1 | 1–1000. |
orientation | — | landscape, portrait or square. |
size | — | large, medium or small. |
color | — | A colour name (blue) or a hex value. |
locale | — | The language of query, e.g. en-US. |
The single-item routes take only the numeric id in the path.
Response
The list routes return one envelope:
| Key | Type |
|---|---|
page, per_page | number — the page you were served |
total_results | number — matches across all pages |
has_more | boolean — whether asking for page + 1 returns more |
photos or videos | array of items |
Each item comes back whole. The fields you will use most:
| Item | Fields |
|---|---|
| Photo | id, width, height, photographer, avg_color, alt, src (the image in several sizes: original, large, medium, small, tiny and more), license |
| Video | id, width, height, duration (seconds), user (id, name), image (a still), video_files (one entry per rendition: link, quality, width, height, file_type), video_pictures, license |
license is a license and attribution string to display alongside the asset. The single-item
routes return the item itself, in the same shape.
{
"page": 1,
"per_page": 3,
"total_results": 8000,
"has_more": true,
"photos": [
{
"id": 3408744,
"width": 6000,
"height": 4000,
"photographer": "Ana Ribeiro",
"avg_color": "#5B7A8C",
"alt": "Mountain lake at dawn with mist over the water",
"src": {
"original": "https://khabot.com/api/v1/media/files/aHR0cHM6Ly…Q.f3K9vR…",
"medium": "https://khabot.com/api/v1/media/files/aHR0cHM6Ly…w.9qLm2x…",
"tiny": "https://khabot.com/api/v1/media/files/aHR0cHM6Ly…A.Tz7cWp…"
},
"license": "<Library> — Photo by Ana Ribeiro · Free to use under the <Library> License"
}
]
}
Trimmed for brevity — a real page holds per_page items, and each item has more
fields and image sizes than shown.
When you show a photo or video, display its license text alongside it.
Using the asset URLs
Every asset URL in a result — src.* on a photo; image,
video_files[].link and video_pictures[].picture on a video — is a
khabot.com URL you can put straight into an <img> or <video>
tag:
- Public — no API key needed to fetch it, so it works in a browser.
- Permanent — the file behind a URL never changes, so it can be cached indefinitely.
- Seekable — range requests are supported, so videos can be scrubbed.
- Not billed — only the search or lookup that returned the URL costs a unit.
The URLs are signed: use them exactly as returned. An altered URL is refused with
403 forbidden, and an unusually heavy burst of asset requests from one client may get
429 rate_limited with a retry-after header.
Billing
Each request bills one unit at the media-search price — a search, a list
page or a single item alike, whatever per_page you ask for. Only successful requests bill: an
invalid request or an unknown id costs nothing, and fetching the asset URLs is never billed.
Examples
# search photos
curl "https://khabot.com/api/v1/media/photos/search?query=mountain+lake&per_page=3&orientation=landscape" \
-H "Authorization: Bearer kb_YOUR_KEY"
# popular videos, second page
curl "https://khabot.com/api/v1/media/videos/popular?page=2" \
-H "Authorization: Bearer kb_YOUR_KEY"
# one photo by id
curl https://khabot.com/api/v1/media/photos/3408744 \
-H "Authorization: Bearer kb_YOUR_KEY"
Errors
| HTTP | code | When |
|---|---|---|
| 400 | bad_request | query missing on a search, page or per_page out of range, an invalid filter value, or a non-numeric id. The message says which. Not billed. |
| 404 | not_found | No photo or video has that id. Not billed. |
| 503 | upstream_unavailable | The library could not be reached. Not billed; safe to retry. |
| 503 | service_not_configured | Media search is not switched on. Not billed. |
Plan, quota and rate-limit walls are the same as every other service — see Errors.