Pexels APIpexels.com ↗
Access Pexels stock photos and videos via API. Search by keyword, filter by color/orientation, browse trending content, photographer galleries, and challenges.
What is the Pexels API?
This API exposes 8 endpoints covering Pexels stock photos and videos, including keyword search, trending feeds, photographer galleries, and challenge listings. The search_photos endpoint accepts filters for color, orientation, and size and returns paginated photo objects with full image URLs, tags, dimensions, and uploader metadata. Video search follows the same pattern and includes direct MP4 source links.
curl -X GET 'https://api.parse.bot/scraper/f2821378-6172-4989-855b-48dce77e55be/search_photos?page=1&size=large&color=red&query=nature&per_page=5&orientation=landscape' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace pexels-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Pexels API — search photos/videos, browse trending, explore photographer galleries."""
from parse_apis.pexels_api import Pexels, Color, Orientation, ChallengeState, MediaNotFound
client = Pexels()
# Search photos with color and orientation filters
for photo in client.photos.search(query="sunset", color=Color.ORANGE, orientation=Orientation.LANDSCAPE, limit=3):
print(photo.title, photo.width, photo.height)
# Search videos and drill into one result's photographer
video = client.videos.search(query="ocean", limit=1).first()
if video:
for gallery_photo in client.user(id=video.user.id).gallery(limit=3):
print(gallery_photo.title, gallery_photo.image_large)
# Browse trending videos
for trending in client.videos.trending(limit=3):
print(trending.title, trending.duration, trending.src)
# List active challenges using the ChallengeState enum
for challenge in client.challenges.list(state=ChallengeState.ACTIVE, limit=3):
print(challenge.title, challenge.prize_title, challenge.media_count)
# Get search suggestions
suggestions = client.searchsuggestions.get(query="mount")
print(suggestions.prefix, suggestions.suggestions[:5])
# Typed error handling for a missing media ID
try:
client.photos.search(query="xyznonexistent999", limit=1).first()
except MediaNotFound as exc:
print(f"Media not found: {exc.media_id}")
print("exercised: photos.search / videos.search / user.gallery / videos.trending / challenges.list / searchsuggestions.get")
Full-text search over Pexels photo library by keyword. Supports filtering by dominant color, orientation, and size. Returns paginated results with photo metadata including title, dimensions, tags, user info, and image URLs at multiple resolutions. Each page returns up to per_page items; advance via the page parameter.
| Param | Type | Description |
|---|---|---|
| page | integer | Page number for pagination |
| size | string | Filter by size: large, medium, small |
| color | string | Filter by dominant color: red, orange, yellow, green, turquoise, blue, violet, pink, brown, black, gray, white |
| queryrequired | string | Search keyword for photos |
| per_page | integer | Number of results per page |
| orientation | string | Filter by orientation: landscape, portrait, square |
{
"type": "object",
"fields": {
"data": "array of photo objects with id, type, and attributes including title, description, width, height, user, tags, and image URLs",
"total_pages": "integer total number of pages",
"current_page": "integer current page number",
"total_results": "integer total number of results"
},
"sample": {
"data": {
"data": [
{
"id": "12377231",
"type": "photo",
"attributes": {
"id": 12377231,
"slug": "a-green-trees-in-the-forest",
"tags": [
"botanical",
"branches",
"dense forest"
],
"user": {
"id": 175964361,
"slug": "danil-lysov-175964361",
"last_name": "Lysov",
"first_name": "Danil"
},
"image": {
"large": "https://images.pexels.com/photos/12377231/pexels-photo-12377231.jpeg?auto=compress&cs=tinysrgb&w=1440",
"small": "https://images.pexels.com/photos/12377231/pexels-photo-12377231.jpeg?auto=compress&cs=tinysrgb&h=130",
"medium": "https://images.pexels.com/photos/12377231/pexels-photo-12377231.jpeg?auto=compress&cs=tinysrgb&w=750"
},
"title": "A Green Trees in the Forest",
"width": 1965,
"height": 3488,
"created_at": "2022-06-04T08:21:04.000Z",
"description": "Dense greenery in a tranquil forest setting."
}
}
],
"total_pages": 1600,
"current_page": 1,
"total_results": 10000
},
"status": "success"
}
}About the Pexels API
Search and Filter
The search_photos and search_videos endpoints both accept a required query string and optional filters: orientation (landscape, portrait, square), size (large, medium, small), and — for photos — color (red, blue, green, orange, yellow, black, white). Both return a data array of media objects with id, type, attributes (title, description, width, height, user, tags, and URLs), plus a pagination object carrying current_page, total_pages, and total_results.
Media Details and Photographer Galleries
Use get_media_details with a numeric media_id (sourced from any search result) to retrieve the full attribute set for a single photo or video, including all tags, translation data, and every available image or video URL. The get_photographer_gallery endpoint accepts a user_id (the user.id field in any search result) and returns that photographer's full upload history in recency order, paginated with per_page and page controls.
Trending Feeds and Cursor Pagination
get_trending_photos and get_trending_videos return the content currently featured on Pexels. These endpoints use cursor-based pagination rather than page numbers — the response pagination object includes a cursor string and a more_data boolean. Pass the cursor value as the seed parameter to retrieve the next page. Video results include file source URLs and preview URLs.
Suggestions and Challenges
get_search_suggestions takes a query prefix (e.g. "mount") and returns an attributes object with the original prefix and an array of autocomplete suggestions. get_challenges lists active and past Pexels photo/video challenges with title, short_description, prize_title, end_date, medium_type, and media_count, filtered by state (active or past).
The Pexels API is a managed, monitored endpoint for pexels.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when pexels.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official pexels.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Building a stock media search UI with keyword, color, and orientation filtering via
search_photos - Populating a trending content carousel using cursor-paginated results from
get_trending_photos - Displaying a photographer's full portfolio by fetching their gallery with
get_photographer_gallery - Embedding video backgrounds by retrieving MP4 source URLs from
search_videosorget_trending_videos - Implementing search autocomplete using prefix-based suggestions from
get_search_suggestions - Listing active creative challenges and their prize details using
get_challengeswith state=active - Fetching full metadata for a known media asset by ID using
get_media_detailsfor tags and dimensions
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Pexels have an official developer API?+
What does the `search_photos` color filter actually accept?+
color parameter accepts one of seven named values: red, blue, green, orange, yellow, black, or white. It filters results by the dominant color of the photo. Hex codes and other named colors are not supported by this parameter.How does pagination differ between search endpoints and trending endpoints?+
search_photos, search_videos, get_photographer_gallery, get_challenges) use standard page-number pagination with page, per_page, current_page, total_pages, and total_results. Trending endpoints (get_trending_photos, get_trending_videos) use cursor-based pagination: pass the cursor string from the previous response's pagination object as the seed input to retrieve the next batch, and check more_data to know if additional pages exist.Does the API return individual video file resolutions or quality variants?+
src URL and a preview_src URL per video object. Separate resolution variants (e.g. 1080p, 720p) are not enumerated as distinct fields in the current response shape. You can fork this API on Parse and revise it to add an endpoint that returns per-resolution file variants if your use case requires them.