Google Yahoo Bing DuckDuckGo Brave

The Cheapest Video Search API for Developers

The ranked video results for a keyword, as JSON: duration, views as a number, publish date, channel, thumbnail and embed URL.

Try for Free API Documentation
Video search from $0.07/1K calls Free to start 5 Video Engines 112 Countries

Google, Yahoo, Bing, DuckDuckGo and Brave all return the same eleven fields in the same order, so adding a second engine to an integration you have already written is one query parameter.

Run a live video search

One real call against the API, no signup and no key. The panel shows the result twice: as a video results page and as JSON.

The rendered view carries each video's thumbnail with its duration badge, the publisher, the view count and the description. The JSON beside it is the exact response your code receives.

Three Ways to Get Video Data

The dedicated endpoint for the ranked video list, the video block inside a web result page, and the same video call submitted as a batch job. Pricing is per category, so the engine you pick never changes what a call costs.

Web SERP

Videos in a web SERP

from $0.03
/1K calls (Scale tier)
  • results.videos on a Deep Search call
  • metadata.hasVideos says whether the page carried one
  • Billed at the Web rate, not the Videos rate
  • Tells you a video block ranked, not who ranked in it
Default$0.60/1K calls
Growth$0.06/1K calls
Scale$0.03/1K calls
All SERP APIs →
Batch

Video jobs in bulk

from $0.07
/1K calls (Scale tier)
  • serp_videos items on POST /api/bulk/jobs
  • A single submission carries up to 200 items
  • Same parameters and same body as the live call
  • GET /api/status lists the job types live for your key
Default$0.10/1K calls
Growth$0.09/1K calls
Scale$0.07/1K calls
Batch reference →

Growth unlocks at a single $100 deposit and Scale at a single $500 deposit. Free to start on eligible endpoints, with the allowance shared across them.

ALSO ON WEB SEARCH

Video stats on ordinary organic rows

A video that ranks in the web results is still a video, and until you know its view count and its age you cannot tell whether it is a serious competitor or an old upload coasting on authority. Add include_video_stats=true to a /api/search or /api/search/quick call and every organic row ends with four more keys — views, publishedTime, duration and publisher — populated on video results and null on every other row. Paid plans, and it costs nothing extra: the call bills at its normal Web rate. Leave the flag off and the response is byte-for-byte what it was before the parameter existed.

See the Web Search endpoint →
{
  "organic": [
    {
      "position": 3,
      "url": "https://www.youtube.com/watch?v=…",
      "views": 1240000,
      "publishedTime": "2026-01-14",
      "duration": "12:45",
      "publisher": "Dev Tutorials"
    }
  ]
}

Abbreviated — title, snippet and displayedUrl are on the row too. The four video keys come last.

Search Videos in One Request

One path, one header, one query parameter to change the engine. The response shape does not move between engines, so a second engine is a copy of the call you already have.

cURL — video search
# The ranked video list for a keyword
curl "https://apiserpent.com/api/videos?q=react+hooks+tutorial&engine=google&country=us&num=20" \
  -H "X-API-Key: YOUR_API_KEY"

# Long-form only, published in the last month, brand-safe
curl "https://apiserpent.com/api/videos?q=react+hooks+tutorial&engine=ddg&duration=long&time=month&safe=strict" \
  -H "X-API-Key: YOUR_API_KEY"

# Just the ranking: position, title, url, duration and nothing else
curl "https://apiserpent.com/api/videos?q=react+hooks+tutorial&engine=yahoo&resolution=720p&format=simple" \
  -H "X-API-Key: YOUR_API_KEY"
JSON Response (abbreviated to one row)
{
  "success": true,
  "query": "react hooks tutorial",
  "type": "videos",
  "engine": "google",
  "country": "us",
  "results": {
    "videos": [
      {
        "position": 1,
        "title": "React Hooks — The Complete Guide",
        "url": "https://www.youtube.com/watch?v=example123",
        "duration": "12:45",
        "source": "www.youtube.com",
        "views": 1240000,
        "thumbnail": "https://i.ytimg.com/vi/example123/hqdefault.jpg",
        "description": "Every hook, in the order you should learn them.",
        "publisher": "Dev Tutorials",
        "embedUrl": "https://www.youtube.com/embed/example123",
        "publishedTime": "2026-01-14"
      }
    ],
    "totalResults": 20
  },
  "meta": {
    "totalVideos": 20,
    "elapsed": "3800ms",
    "timestamp": "2026-09-07T10:47:33.000Z"
  }
}

Note the two values you would otherwise have written a parser for: views arrives as 1240000, not as the string "1.2M views", and publishedTime arrives as 2026-01-14, not as "8 months ago". Sorting by view count or bucketing by age is arithmetic, not string handling.

Every Field a Video Call Returns

Eleven keys per row, in a fixed order, on every engine. Nothing here needs a parser of your own, and nothing changes shape between calls.

results.videos[]

  • position — integer
  • title — string | null
  • url — string | null
  • duration — string | null
  • source — string | null
  • views — number | null
  • thumbnail — string | null
  • description — string | null
  • publisher — string | null
  • embedUrl — string | null
  • publishedTime — string | null
  • totalResults — integer

Request parameters

  • q — the search query
  • engine — google, yahoo, bing, ddg (default), brave
  • country — 112 codes, default us
  • num — a ceiling on the list returned
  • duration — short, medium, long
  • resolution — see the filter cards below
  • freshness — h, d, w, m, y
  • time — day, week, month, year
  • safe — off, moderate, strict
  • format — full or simple
  • timeout — seconds you will wait

What the values mean

position is the 1-based rank inside the list you were handed and never skips a number, which is what makes a position log safe to diff week over week.

source is the host the video is served from, such as www.youtube.com, so you can measure how much of a query's video surface sits on one platform. publisher is the uploader's channel name, never the platform word: a row that names only the platform returns null, because the platform is already in source.

When a call comes back short

num is a ceiling, not a promise. It caps the list; what fills it is however many videos the result page ranks for that query.

When fewer rows arrive than you asked for, the response says so instead of leaving you to count. A top-level delivery block carries requested, returned, a short reason and a plain-English note, plus an async_endpoint pointer where the batch form can finish the job; meta.partialResults carries the same numbers. The field set never changes on a short answer.

What is video SERP data, and why teams use it

Video is the one search surface where your asset almost never lives on your own domain, so the questions you can ask of it are different — and so is the data you need to answer them.

Video results are their own ranking surface

A page can hold position 3 in web results and be absent from the video results for the same keyword. The two lists are filled by different assets, judged on different signals, and dominated by different names — usually channels, not domains.

That makes a web rank tracker blind to half your visibility on any query with video intent. /api/videos returns the video list itself, with position on every row, so you can track it the same way you track the blue links.

The numbers arrive as numbers

Video metadata is displayed for humans: 1.2M views, 8 months ago, Streamed 2 years ago. Every one of those is a parsing job, and every one of them is a place a rounding rule can quietly cost you a factor of a thousand.

Here views is 1240000 and publishedTime is 2026-01-14. "Median views in the top ten" and "median age of a ranking video" become one expression instead of a parser you have to maintain.

Eleven keys, always present, one order

Every row carries all eleven keys whether or not the result had a value for each. A missing value is null; it is never a missing key, and the order never changes between calls or between engines.

So you write one parser and point it at any engine, and a row that arrives thin cannot throw a KeyError in the middle of a nightly run. Adding a second engine to a working integration is a single query parameter.

Filters that match how video is judged

Runtime, upload date and safety are ranking-relevant on video in a way they are not on web search, so they are first-class request parameters: duration, resolution, freshness (or its time alias) and safe.

Run the same keyword at duration=short and again at duration=long and you can see which runtime the surface is actually rewarding before you brief a single edit.

Narrow the List Before You Pay for It

Six request parameters, all optional, all validated. A value outside the accepted set returns a 400 naming the parameter at fault rather than quietly serving you the unfiltered list.

duration

short, medium or long on ddg, yahoo and bing. The one filter that answers a content question directly: which runtime ranks for this keyword?

resolution

high or standard on ddg; 360p, 480p, 720p, hd or 1080p on yahoo and bing. A request filter, not a returned field.

freshness

Last hour, day, week, month or year: h, d, w, m, y, and the 1h, 1d, 7d, 1m, 1y spellings the other endpoints use.

time

An alias for freshness in words: day, week, month, year. Send both and freshness wins, because it is the finer-grained of the two.

safe

off, moderate or strict. Video is a user-generated surface, so this is the parameter that decides whether a feed is safe to render on your own site.

country

112 codes, default us. The ranked video set moves more between markets than the web list does, so a single locale is rarely the whole picture.

What Teams Actually Pull Video Results For

Four jobs that account for most video search traffic, and the fields each one needs.

Video rank tracking for a channel

On video you track a name, not a domain, because your asset sits on someone else's host. Match on publisher across your keyword list and log the position it holds.

One call per keyword, at the flat Videos rate. Run it nightly and you have the same time series you keep for web rankings, on the surface a web rank tracker cannot see.

Share of the video surface

Group the rows for a keyword set by publisher and by source and you get two numbers that matter to a category owner: which channels hold the video results, and how much of the surface sits on one platform.

Both fields are on every row, so the whole analysis is one pass over the responses you already stored.

Content planning from what already ranks

Before commissioning a video, read the set that ranks today: the median views is the bar to clear, the spread of publishedTime says whether the query is churny or settled, and duration says what length is being rewarded.

Because views is a number and publishedTime is a date, those three answers are a single aggregation rather than a parsing project.

Video feeds and embeds in your own product

A results row carries everything a card needs: thumbnail, duration, title, publisher, views, publishedTime and an embedUrl for the player. No second lookup per video.

Pair it with safe=strict before anything renders on a page your customers see, and with freshness when the feed is meant to look current.

Bash — nightly video position log
# One line per keyword: date, keyword, your channel's best video position (0 if unranked).
# On video you match the channel name, not your domain — the video is not hosted by you.
CHANNEL="Dev Tutorials"

while IFS= read -r kw; do
  pos=$(curl -s -G "https://apiserpent.com/api/videos" \
      --data-urlencode "q=$kw" \
      -d "engine=google" -d "country=us" -d "num=30" \
      -H "X-API-Key: $SERPENT_KEY" \
    | jq -r --arg c "$CHANNEL" \
        '[.results.videos[] | select(.publisher == $c)][0].position // 0')
  echo "$(date -u +%F),$kw,$pos" >> video-positions.csv
done < keywords.txt
Bash — the shape of the videos that rank
# The bar to clear for one keyword: median view count, oldest and newest upload,
# and how many of the ranking videos come from one host.
curl -s -G "https://apiserpent.com/api/videos" \
    --data-urlencode "q=react hooks tutorial" \
    -d "engine=google" -d "country=us" -d "num=20" \
    -H "X-API-Key: $SERPENT_KEY" \
  | jq '{
      ranked:       (.results.videos | length),
      median_views: ([.results.videos[].views | numbers] | sort | .[(length / 2) | floor]),
      oldest:       ([.results.videos[].publishedTime | strings] | min),
      newest:       ([.results.videos[].publishedTime | strings] | max),
      by_host:      (.results.videos | group_by(.source) | map({(.[0].source // "unknown"): length}) | add)
    }'

Both snippets run against a live key and use only fields listed above. numbers and strings in the jq filters skip the rows where a value was null, which is why the always-present-key rule matters in practice.

Video Search API Questions

Every video row carries the same eleven fields, in the same order: position, title, url, duration, source, views, thumbnail, description, publisher, embedUrl and publishedTime. views is a number, not a display string. publishedTime is a date in YYYY-MM-DD form. source is the host the video is served from, such as www.youtube.com, and publisher is the uploader's channel name; a row that names only the platform returns null there, because the platform is already in source. Every key is always present, so a value the result did not carry comes back as null rather than as a missing key.
Video search is $0.10 per 1,000 calls on the Default tier, $0.09 per 1,000 on Growth (a single $100 deposit) and $0.07 per 1,000 on Scale (a single $500 deposit). Pricing is per category, so the engine you choose never changes the rate: google, yahoo, bing, ddg and brave all bill at the Videos rate. Free to start on eligible endpoints, and video search is one of them.
num is a ceiling, not a promise. It caps the list you receive; what fills that list is however many videos the result page actually ranks for your query, and in measurement a single call has returned roughly 50 to 60 videos at the maximum. When fewer rows come back than you asked for, the response says so rather than leaving you to count: a top-level delivery block carries requested, returned, a short reason and a plain-English note, and meta.partialResults carries the same numbers. Nothing about the field set changes on a short answer.
Yes. duration takes short, medium or long on ddg, yahoo and bing. resolution takes high or standard on ddg, or 360p, 480p, 720p, hd and 1080p on yahoo and bing. freshness narrows to the last hour, day, week, month or year (h, d, w, m, y, and the 1h, 1d, 7d, 1m, 1y spellings), and time is an alias that accepts day, week, month and year; if both are sent, freshness wins because it is the finer-grained of the two. safe takes off, moderate or strict. A value outside the accepted set returns a 400 naming the parameter at fault. duration is also a returned field; resolution is a request filter only.
embedUrl is an embeddable player URL where the result carries one, and null where it does not, so you can render a player without a second lookup. thumbnail is a direct image URL: for a YouTube video it is always that video's own YouTube thumbnail, on every engine, so the same video gives you the same image whichever engine you asked; for any other video it is the thumbnail the result carries when there is one, and null otherwise. Rendering a card needs no extra call: title, duration, publisher, views and publishedTime are all on the same row.
country accepts 112 codes and defaults to us, which matters more on video than on web search because the ranked set shifts substantially between markets. language is not accepted on /api/videos: send it and it is ignored rather than rejected, so do not build a localisation strategy on it. Use country, and use the web, news or image endpoints when you need a language code.

Start using the Video Search API

free API calls, no card. Video search from $0.07 per 1,000 calls on Google, Yahoo, Bing, DuckDuckGo and Brave.

Try for Free

Related guides

More on video, channels and the rest of the search surface.

YouTube APIVideo, channel and playlist detail once search has found the video. Track Competitor ChannelsWatch a rival channel's uploads and cadence with an API. Search Everywhere OptimizationMulti-surface visibility strategy for 2026, video included. Image Search APIThe same contract for image results: thumbnails, dimensions, source page. News APIHeadlines with source and published time, from $0.01/1K. All SERP APIsWeb, news, images and video across five engines.