Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/budgetpixel:budgetpixel-depth-maps-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
contact:
email: support@budgetpixel.com
name: BudgetPixel Support
description: 'The BudgetPixel developer API for programmatic image, video, music and
sound-effect generation.
Generation is **asynchronous**: you create a job, then poll its status until it
reaches a terminal state (`succeeded` / `failed`). You are charged in credits
only on success — never for failures, timeouts, or content blocked before
generation.
**Authentication.** All requests require an API key sent as a bearer token:
Authorization: Bearer bpx_live_xxx
Create and manage keys from your BudgetPixel account dashboard. The developer
API is available on **every paid plan**. On the **Free** plan, API keys can call
the free library searches only: `GET /v1/stock/images`,
`GET /v1/stock/sound-effects` and `GET /v1/stock/music`.
**Pricing.** API usage is metered in credits at each model''s published price
(see `GET /v1/models`), and your plan''s model discounts and active promotions
apply to API charges exactly as they do on the web — `POST /v1/cost` quotes
your discounted price. Pro and Ultra plans include a daily free-models
allowance (a shared pool of free generations per day across qualified image
models such as FLUX 2 Klein and Qwen-Image) that covers API
requests too — the standard price applies once the day''s pool is used.
Other promotional free daily generations remain web/app-only. Failed
generations are never charged.
**Rate limits.** Requests are limited per minute: **600 requests/min per API
key** and **1200 requests/min per source IP** (defaults; subject to tuning).
Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and
`X-RateLimit-Reset` (seconds until the window resets). Exceeding a limit
returns HTTP `429` with a `Retry-After` header — wait that long before
retrying. Rejected requests still count against the window, so a tight retry
loop keeps you limited; back off instead. Generation jobs additionally have a
per-plan concurrency cap (the same one as the web workshop), independent of
these request limits. `POST /v1/uploads` also has a dedicated **60 uploads/min
per account** cap (it''s free/unmetered) on top of these limits. Every `429`
this API returns carries `Retry-After`, including a full concurrency queue
(a suggested wait) and the monthly spend limit (seconds until the month
resets).
**Output retention.** Generated files are kept for 24 hours after the job is
created. Job status responses give the exact time as `expires_at`; after it,
`expired` is `true` and no download URLs are returned.'
title: BudgetPixel Depth Maps API
version: '2026-06-20'
servers:
- description: Production
url: https://api.budgetpixel.com/v1
security:
- ApiKeyAuth: []
tags:
- description: Turn a video into a depth map video to guide other video models with its structure and motion
name: Depth Maps
paths:
/depth-maps/{id}:
get:
description: 'Poll until `status` is `succeeded`. The depth video is returned as a
short-lived signed `video_url` (valid for several hours; re-call for a fresh
URL anytime — the underlying object is deleted 24h after generation).
The depth video is an H.264 MP4 at the input''s frame size (up to 1080p,
or the `resolution` you asked for) and frame rate (up to 30 fps). In
grayscale, near is white and far is black.
With `face_mesh` or `include_face_landmarks`, the response adds
`face_mesh` (how much of the clip had a face, and each face''s frames)
and, with `include_face_landmarks`, a signed `face_landmarks_url`.'
operationId: getDepthMapJob
parameters:
- description: The opaque job id returned by the create endpoint.
in: path
name: id
required: true
schema:
type: string
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/DepthMapJob'
description: Current job status. `video_url` is populated once succeeded.
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'404':
$ref: '#/components/responses/NotFound'
summary: Get depth map job status
tags:
- Depth Maps
/depth-maps/video-depth-anything:
post:
description: 'Turns a video into a depth map video: near is white, far is black, steady from frame to frame, at the input''s size (up to 1080p) and frame rate (up to 30 fps). Feed it to a video model as a structure or motion reference. Three sizes: small is fastest, base adds edge detail, large draws the finest detail (hair, thin poles, distant people) and is the steadiest. Priced per second of the INPUT video, rounded up, 5 seconds minimum: small 20, base 30, large 40 credits/second (input up to 30 seconds, ≤100MB). Output is H.264 MP4. Optional face mesh, at no extra charge: face_mesh draws each face''s mesh (eyes, brows and lips in colour) over the depth so a video model keeps lip, eye and head movement, and include_face_landmarks returns per-frame landmarks, expression scores and head pose as JSON.
**Asynchronous.** Returns a job `id` (the video is not in this response). Poll `GET /v1/depth-maps/{id}` until `status` is `succeeded` — the depth video''s URL is in that response''s `video_url`.
Examples, sample output and pricing: Video Depth Anything'
operationId: createDepthMap_video_depth_anything
requestBody:
content:
application/json:
schema:
properties:
colormap:
default: grayscale
description: grayscale (near = white) is what video models take as a depth reference; turbo, inferno, magma and viridis colour it for viewing.
enum:
- grayscale
- turbo
- inferno
- magma
- viridis
type: string
face_mesh:
default: false
description: Draw a mesh over each face (up to max_faces), with eyes, brows and lips in colour, so a video model given the depth map keeps lip, eye and head movement. Faces are found automatically; a face turned to full profile gets no mesh. No extra charge.
type: boolean
include_face_landmarks:
default: false
description: 'Also return face_landmarks_url: a JSON file with 478 3D points, 52 expression (blendshape) scores and a head-pose matrix per face per frame. Works with or without face_mesh. The file is kept 7 days. No extra charge.'
type: boolean
keep_audio:
default: false
description: Copy the input's audio into the depth video.
type: boolean
max_faces:
default: 4
description: Most faces tracked at once (1-4), largest first. Applies to face_mesh and include_face_landmarks.
maximum: 4
minimum: 1
type: integer
resolution:
default: auto
description: The output's short side; auto keeps the input's size up to 1080p. Never upscales. The price is the same at every resolution.
enum:
- auto
- 360p
- 480p
- 720p
- 1080p
type: string
side_by_side:
default: false
description: Return the input on the left and the depth map on the right, twice the width.
type: boolean
size:
default: small
description: 'Model size, which sets the per-second rate: small 20, base 30, large 40 credits.'
enum:
- small
- base
- large
type: string
video:
description: The video to turn into a depth map (up to 30 seconds, MP4/MOV/WebM, ≤100MB). A public video URL or an uploaded-file URL from POST /v1/uploads (videos are passed by URL, not inlined).
type: string
x-bpx-media: video
required:
- video
type: object
required: true
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/CreateDepthMapResponse'
description: Job accepted.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/TooManyRequests'
summary: Make a depth map with Video Depth Anything
tags:
- Depth Maps
components:
schemas:
CreateDepthMapResponse:
properties:
credits:
charged when it succeeds.: null
description: Total price of this job (seconds x the size's per-second rate). Held now
type: integer
id:
description: Opaque job id (`dpt_...`) — use it to poll status.
type: string
message:
type: string
model:
type: string
seconds:
description: Billed duration — the input video's length, rounded up to whole seconds, at least 5.
type: integer
size:
description: The model size the job runs at.
enum:
- small
- base
- large
type: string
status:
$ref: '#/components/schemas/JobStatus'
type: object
DepthMapJob:
allOf:
- $ref: '#/components/schemas/MotionJob'
- properties:
face_landmarks_url:
description: 'With `include_face_landmarks`, once `status=succeeded`: a short-lived signed URL to a JSON
file (`format: budgetpixel-face-landmarks/1`) with, per frame and per face, 478 `[x, y, z]`
landmarks (x and y as fractions of the frame), 52 blendshape scores (names in
`blendshape_names`) and a 4x4 head-pose `matrix`. Kept 7 days.
'
format: uri
type: string
face_mesh:
description: Present when the job asked for `face_mesh` or `include_face_landmarks`, once the worker has run.
properties:
coverage:
description: Share of frames with at least one face, 0 to 1. 0 means no face was found, so nothing was drawn.
type: number
drawn:
description: 'Whether the mesh was drawn on the video (`face_mesh: true`).'
type: boolean
faces:
description: One entry per tracked face.
items:
properties:
first_frame:
type: integer
frames:
description: Frames this face has a mesh in
including bridged gaps.: null
type: integer
id:
type: integer
interpolated_frames:
description: Frames filled in across a short gap in tracking (up to 0.3 s).
type: integer
last_frame:
type: integer
type: object
type: array
frames:
description: Frames in the output.
type: integer
frames_with_face:
type: integer
type: object
type: object
QueueFull:
description: '`429` body when your account already has as many jobs of this kind
(image, video or audio) in flight as its concurrency cap allows. Submit
the next job when one of your running jobs finishes.
'
properties:
active_jobs:
description: Jobs of this kind in flight right now.
type: integer
code:
enum:
- queue_full
type: string
error:
description: Human-readable message.
type: string
queue_full:
enum:
- true
type: boolean
queue_limit:
description: Your concurrency cap for this kind of job.
type: integer
retry_after_seconds:
description: Same value as the `Retry-After` header.
type: integer
required:
- error
- code
- queue_full
- queue_limit
- active_jobs
- retry_after_seconds
type: object
Error:
properties:
error:
properties:
code:
description: Stable machine-readable code.
example: model_not_available
type: string
message:
type: string
type:
description: Error category.
example: invalid_request_error
type: string
required:
- type
- code
- message
type: object
required:
- error
type: object
ModerationBlocked:
description: Returned (with HTTP 400) when the input content moderation gate blocks a generation request. The block is a property of the request's prompt or input media — reword the prompt or change the input and retry. Branch on `restriction_reason`, which is stable and machine-readable.
properties:
error:
description: Human-readable explanation of the block.
type: string
restriction_reason:
description: Stable machine-readable block reason.
enum:
- input_csam
- input_explicit_adult
- input_upload_nudity
- input_celebrity_likeness
- strict_model_nsfw
type: string
required:
- error
- restriction_reason
type: object
JobStatus:
description: Lifecycle state. `succeeded`/`failed`/`timeout` are terminal.
enum:
- pending
- starting
- processing
- completing
- succeeded
- failed
- timeout
type: string
MotionJob:
properties:
completed_at:
format: date-time
type: string
created_at:
format: date-time
type: string
error_message:
type: string
id:
type: string
model:
type: string
status:
description: Lifecycle state. `succeeded`/`failed`/`canceled` are terminal.
enum:
- pending
- processing
- succeeded
- failed
- canceled
type: string
video_codec:
description: Codec of the MP4 at `video_url`; present once `status=succeeded`. Video upscales are `h265` (HEVC, 10-bit); motion-control outputs are `h264`.
enum:
- h264
- h265
type: string
video_codec_note:
description: Present only when `video_codec` is `h265` — a short explanation of where H.265 plays and what to do when it does not.
type: string
video_url:
description: Short-lived presigned URL; present once `status=succeeded`.
format: uri
type: string
type: object
responses:
TooManyRequests:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Error'
- $ref: '#/components/schemas/QueueFull'
description: 'A limit was reached. Every `429` carries `Retry-After` (seconds). The
per-minute rate limit, the upload limit and the hourly API post cap answer
with the `Error` envelope, code `rate_limited`. The monthly spend limit answers with
code `monthly_spend_limit_reached`, and its `Retry-After` counts down to the
start of next month (raising the limit in the console clears it sooner).
A full concurrency queue answers with the flat `QueueFull` body (3D jobs:
the `Error` envelope with code `queue_full`); its `Retry-After` is a
suggested wait, because a slot frees as soon as one of your running jobs
finishes.
'
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
minimum: 1
type: integer
NotFound:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: The requested job was not found.
Unauthorized:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Missing or invalid API key.
BadRequest:
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/Error'
- $ref: '#/components/schemas/ModerationBlocked'
description: The request was malformed, referenced an unavailable model, or was blocked by input content moderation (moderation blocks carry a `restriction_reason` — see ModerationBlocked).
Forbidden:
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
description: Authenticated but not permitted (plan gate, ownership, account restriction). Content-moderation blocks are 400, not 403.
securitySchemes:
ApiKeyAuth:
bearerFormat: bpx_live_*
description: 'API key as a bearer token: Authorization: Bearer bpx_live_xxx'
scheme: bearer
type: http