PixabayMediaClient
PixabayMediaClient implements the same provider-neutral MediaClient contract against the Pixabay API. Use it for photo and video search with Pixabay-specific filters (category, dimensions, editor's choice) when Pexels curated content or Pexels-only filters are not required.
Installation
pnpm add @media-sdk/core@^0.3.0Sign up for a free API key at pixabay.com/api/docs.
Constructor
The constructor mirrors PexelsMediaClient: ApiKeyProvider plus optional cache and httpClient.
| Option | Type | Default | Description |
|---|---|---|---|
cache | Cache | MemoryCache (60s TTL) | In-memory cache with request deduplication |
httpClient | HttpClient | FetchHttpClient | Custom transport for testing or proxying |
Authentication difference: Pixabay sends the API key as a key= query parameter on every request, not an Authorization header. You still wrap the key in ApiKeyProvider — the client handles wire formatting.
import {
ApiKeyProvider,
PixabayMediaClient,
} from "@media-sdk/core";
const auth = new ApiKeyProvider(process.env.PIXABAY_API_KEY!);
const client = new PixabayMediaClient(auth);import {
ApiKeyProvider,
MemoryCache,
PixabayMediaClient,
} from "@media-sdk/core";
const client = new PixabayMediaClient(
new ApiKeyProvider(process.env.PIXABAY_API_KEY!),
{ cache: new MemoryCache(120_000) },
);In browser apps (Vite), use import.meta.env.VITE_PIXABAY_API_KEY.
MediaClient methods
| Method | Pixabay support |
|---|---|
searchPhotos(params) | ✅ |
searchVideos(params) | ✅ |
getPhoto(id) | ✅ |
getVideo(id) | ✅ |
getCuratedPhotos(params?) | ❌ throws UNSUPPORTED_CAPABILITY |
on / trackView / trackDownload | ✅ |
Photo search
import {
ApiKeyProvider,
PixabayMediaClient,
} from "@media-sdk/core";
const client = new PixabayMediaClient(
new ApiKeyProvider(process.env.PIXABAY_API_KEY!),
);
const result = await client.searchPhotos({
query: "nature",
page: 1,
perPage: 20,
});
console.log(result.items);
console.log(result.pagination);const result = await client.searchPhotos({
query: "nature",
page: 1,
perPage: 20,
photoFilters: {
orientation: "landscape",
color: "green", // maps to Pixabay `colors` param
category: "nature",
minWidth: 1920,
minHeight: 1080,
editorsChoice: true,
locale: "en",
},
});const videos = await client.searchVideos({
query: "ocean",
page: 1,
perPage: 15,
videoFilters: {
category: "nature",
minWidth: 1280,
minHeight: 720,
editorsChoice: true,
},
});Single media
const photo = await client.getPhoto(12345);
const video = await client.getVideo(67890);Curated photos
Pixabay has no curated-photos endpoint. Calling getCuratedPhotos() throws:
import { MediaError } from "@media-sdk/core";
try {
await client.getCuratedPhotos({ page: 1, perPage: 20 });
} catch (error) {
if (error instanceof MediaError) {
console.error(error.code); // "UNSUPPORTED_CAPABILITY"
}
}Guard with capabilities instead of catching:
import { getCapabilities } from "@media-sdk/core";
const caps = getCapabilities(client);
if (caps.operations.curatedPhotos) {
// never true for PixabayMediaClient
}Supported filters
| Filter | Photos | Videos |
|---|---|---|
orientation | ✅ | ❌ |
size | ❌ | ❌ |
color | ✅ | ❌ |
category | ✅ | ✅ |
minWidth / minHeight | ✅ | ✅ |
editorsChoice | ✅ | ✅ |
locale | ✅ | ❌ |
Passing an unsupported filter (for example size on photo search) throws UNSUPPORTED_FILTER. See Filters.
Color values
PhotoSearchFilters.color accepts both Pexels and Pixabay color enums. Pixabay adds values such as grayscale and transparent. Invalid values for the active provider throw INVALID_FILTER_VALUE.
Video rendition mapping
Pixabay video hits are normalized into VideoFile entries for each available rendition:
| Pixabay rendition | VideoFile.quality |
|---|---|
large | "large" |
medium | "medium" |
small | "small" |
tiny | "tiny" |
Each file includes link, width, height, and fileType: "video/mp4".
Hotlinking requirement
Pixabay requires serving images and videos from the URLs returned by the API (previewURL, webformatURL, largeImageURL, video rendition URLs). Do not download and re-host media on your own CDN — use the normalized Photo.src and Video.videoFiles links directly.
Caching compliance
The SDK caches API JSON responses in memory (same as Pexels). Pixabay's terms restrict how long you may cache API responses. Tune MemoryCache TTL or inject a custom Cache implementation if your usage requires stricter compliance:
import { MemoryCache, PixabayMediaClient } from "@media-sdk/core";
const client = new PixabayMediaClient(auth, {
cache: new MemoryCache(30_000), // shorter TTL
});Pagination
Pixabay computes hasNext / hasPrevious from page, perPage, and totalHits. Unlike Pexels, nextPage and prevPage URL fields are not populated. Use page numbers for navigation. See Pagination.
Capabilities
import { getCapabilities } from "@media-sdk/core";
const caps = getCapabilities(client);
// caps.operations.curatedPhotos === false
// caps.photoFilters.category === true
// caps.photoFilters.size === falseNext steps
- PexelsMediaClient — curated photos and Pexels filters
- Provider comparison — full matrix and UI gating patterns
- Capabilities —
getCapabilitiesand React hook