Skip to main content
The official Python client for the VidNavigator API. Every response is a typed Pydantic model (v1 and v2 both work), and long-running work such as speech-to-text, extraction, tweet analysis and TikTok scraping runs as background jobs, so media of any length works with a single call. It ships a synchronous client and an asyncio client with the same methods. PyPI version Python versions License

PyPI package

vidnavigator 2.1.0 on the Python Package Index.

GitHub repository

Source code, issues and changelog.
This page documents version 2.1.0. Coming from 1.x? See Upgrading from 1.x.

Installation

For the asyncio client, install the async extra, which adds httpx >= 0.23:
Requirements: Python 3.8+, requests >= 2.31 and pydantic >= 1.10 (installed automatically).

Authentication

Get your API key in the Developer Dashboard.

Configuration

The client’s timeout applies to each HTTP request. It is separate from the timeout argument of job methods such as transcribe_video(timeout=...), which limits how long to wait for a whole background job. Use the client as a context manager to close its HTTP session automatically. One client can be reused for any number of calls; if you use threads, create one client per thread. For asyncio code, use AsyncVidNavigatorClient.

Quick start

Which method should I use?

“When the job finishes” methods run as background jobs: they block until the result is ready, however long the media is. Each one also has a submit_* version that returns immediately.

Supported platforms


Transcripts

Captions from any platform

get_transcript handles every supported platform; the API detects the platform from the URL. Instagram has no captions, so use transcribe_video for it.
Pass transcript_text=True to get one plain string instead of segments:
get_youtube_transcript still works as a deprecated alias for get_transcript.

Speech-to-text

For videos without captions, transcribe_video runs speech-to-text as a background job: it submits the video, waits for the transcript, and returns it. Long videos work exactly like short ones.

Instagram carousels

Pick one video with ?img_index=N in the URL, or transcribe all of them:

Captions first, speech-to-text as a fallback

Captions are faster and cheaper than speech-to-text, so a common pattern is to try them first:

AI analysis

Get a summary, the people, places and key subjects, and a direct answer to a natural-language question. query is optional.
Pass transcript_text=True to also receive the transcript as one string. See the Analyzing Videos guide for billing details.

Structured extraction

Describe the fields you want and the API fills them in from the transcript. See the Data Extraction guide for schema design tips.

From an online video

extract_video_data runs as a background job. With transcribe=True (the default), a video without captions is transcribed first, however long it is. Set transcribe=False to never run speech-to-text. The extracted fields are in resp.data, and the video’s metadata (a VideoInfo) in resp.video_info, so you don’t need a separate get_transcript(metadata_only=True) call.
video_info on extraction results requires 2.1.0. In 2.0.0 it is always None.

Schema format

Each field needs a type and a description. A schema can have at most 10 top-level fields and 3 levels of nesting.
An invalid schema raises BadRequestError with error_code == "invalid_schema" before anything is transcribed or billed.

From a schema file

Keep schemas in JSON or YAML files and pass schema_file instead of schema:

From an uploaded file

Token usage


Tweet claim analysis

Videos attached to the tweet (or to the tweet it quotes) are transcribed in full, so this runs as a background job too. claim_type, intent, tone, emotion and authority are based on the original tweet text only. See the Tweet Claim Analysis guide.

Background jobs

Speech-to-text, extraction, tweet analysis and TikTok operations run as background jobs on VidNavigator’s servers. The SDK always uses the async endpoints, so media of any length works without special handling. Each job operation comes in two shapes, which take the same parameters: With a handle, include_usage, timeout and (for TikTok) limit are passed to job.result() instead.

Submit now, collect later

Polling is free and not rate-limited. A job’s result stays readable for 1 hour after it finishes, and reading it does not consume it.

Timeouts: never lose the task_id

Blocking calls and result() wait up to timeout seconds (default one hour), then raise JobTimeoutError. The job keeps running on the server, and the error carries the task_id and a ready-to-use handle:
Later, or from another process, rebuild the handle from a saved id with resume_job:

Failures

A failed job raises the exception that matches its error.http_status, so the same except clauses work for direct calls and jobs. A failed job has all its charges reverted.
To inspect a failure without an exception, use job.wait(raise_on_failure=False) and read resp.data.error. Some errors happen at submit time, before a job exists:

Recipes

Process many videos at once

Submit every job first, then collect the results. All the jobs run at the same time on the server:
With jobs that take 60 s, 40 s and 90 s, the batch takes about 90 s (the slowest job). Calling the blocking transcribe_video in a loop would take 190 s. To let one job fail without stopping the batch, catch errors per job:

Handle results as soon as they finish

Stay under the running-job limit

Past your account’s limit, a submit raises TooManyActiveJobsError and no task is created. For large batches, keep a bounded number of jobs running:

Survive a restart

Save the task_id when you submit, and resume with resume_job:

Transcribe every video of a TikTok profile


Async client

AsyncVidNavigatorClient has the same methods, arguments and return types as VidNavigatorClient, as coroutines. Use it from asyncio code such as FastAPI, aiohttp, Discord bots or agent frameworks: while a job runs, waiting uses asyncio.sleep, so the event loop keeps serving other work.
New in 2.1.0. Install the async extra: pip install "vidnavigator[async]==2.1.0".

Many jobs at once

asyncio.gather runs every call concurrently. Each job is submitted immediately and polled in the background of the same event loop:
To cap how many jobs run at once (see the running-job limit), wrap each call in an asyncio.Semaphore:

Async job handles

submit_* methods return an AsyncJob. It has the same members as Job, with status(), done(), refresh(), wait() and result() as coroutines.
Timeouts work as in the sync client: JobTimeoutError carries the task_id and an AsyncJob handle, so await exc.job.result() resumes waiting. client.resume_job(job_type, task_id) rebuilds a handle later; it is a plain method, not a coroutine.

In a FastAPI app

Create one client for the app’s lifetime and share it across requests:

Async configuration

  • Close the client with await client.aclose(), or use async with. A client you pass as http_client is not closed for you.
  • The webhook helpers are plain functions and work unchanged in async code.
  • The deprecated aliases get_youtube_transcript and search_videos are not available on the async client. Use get_transcript and search_youtube.

Webhooks

Every job method, blocking or submit_*, accepts a webhook_url. Webhooks are optional: polling always works, whether or not a webhook is configured.
  • The URL must be a publicly reachable https address; private, loopback and link-local hosts raise BadRequestError.
  • A default webhook can be set in Studio → API. A per-request webhook_url overrides it, and webhook_url="" opts a single job out.

Receive and verify deliveries

construct_webhook_event checks the HMAC-SHA256 signature and the timestamp, then returns a typed WebhookEvent. Always pass the raw request body:
  • event.data.result also holds the result as a plain dict, unless it was over 256 KB (data.result_truncated is True).
  • For extract_video.completed events, event.data.video_info holds the video’s metadata as a plain dict. It is sent even when the result was truncated.
  • For TikTok events, event.data.result is only a summary (stats, download_url_available); read the videos with client.resume_job("tiktok_search", event.data.task_id).result().
  • Deliveries more than 5 minutes old are rejected; change the window with tolerance_seconds= (or None to skip the check).
  • verify_webhook_signature(body, header, secret) verifies without parsing and raises the same WebhookSignatureError.
Event types are transcribe.*, extract_video.*, tweet_statement.*, tiktok_profile.* and tiktok_search.*, each .completed or .failed. See Webhooks for the full delivery contract.

TikTok

Profile scraping

scrape_tiktok_profile runs a background job and returns the first page of videos:
video.published_at is a Python datetime, and views, likes, reposts and comments are integers. To start the scrape without waiting, use submit_tiktok_profile_scrape(...), then job.result(limit=50). Read the remaining pages:
Or download the full result from the short-lived (about 1 hour) download_url. Calling get_tiktok_profile_scrape again mints a fresh link.
search_tiktok works the same way and returns the first page of results:
Read further pages with get_tiktok_search(task_id, cursor=...), exactly as for profiles. See the Searching TikTok guide.

Search YouTube

Runs a YouTube search, then ranks the results with AI analysis of their transcripts:
search_videos still works as a deprecated alias for search_youtube.

Search your uploaded files


Files

Supported formats: mp4, webm, mov, avi, wmv, flv, mkv, m4a, mp3, mpeg, mpga, wav.

Upload and process

With wait_for_completion=False (the default), the upload returns immediately and processing continues in the background. Check get_file(file_id).data.file_info.status until it is "completed".

Retrieve a file and its transcript

List and filter files

Manage files

Namespaces

Group uploaded files by project, client or topic, then scope listings and searches to them.

Usage and billing

Per-call usage

Pass include_usage=True to see which meters a call charged, how many credits were deducted, and how many LLM tokens were used. It is supported by get_transcript, transcribe_video, analyze_video, analyze_file, extract_video_data, extract_file_data, search_youtube, search_files, get_tweet_statement, the TikTok methods, and job.result(include_usage=True).
Meters: standard_request, residential_request, transcription_hour, analysis_request, search_request and scene_analysis_hour. See Usage & Costs.

Account usage

client.health_check() returns the API status and needs no authentication.

Error handling

Every API error maps to a specific exception, all inheriting from VidNavigatorError:
API exceptions carry the details of the error response:
See Errors for every API error code.

What’s new in 2.1.0

  • Async client: AsyncVidNavigatorClient and AsyncJob, with the same methods as the sync client, as coroutines. Install with pip install "vidnavigator[async]".
  • video_info on extraction: extract_video_data(...) and submit_extract_video_data(...).result() now return the video’s metadata in resp.video_info, and extract_video.completed webhook events carry it in event.data.video_info.
  • Python 3.8+: support for Python 3.7 was dropped.
No other changes are needed to upgrade from 2.0.0.

Upgrading from 1.x

Version 2.0 runs speech-to-text, extraction, tweet analysis and TikTok operations as background jobs. Most code keeps working unchanged. Check these points: New in 2.0: submit_transcribe_video, submit_extract_video_data, submit_tweet_statement, scrape_tiktok_profile, search_tiktok, resume_job, webhook_url on every job method, sort_by and published_within for TikTok search, the webhook helpers, and status_code / error_code / docs_url / payload on every API exception.

Resources

PyPI

Package page and release history.

GitHub

Source code and issue tracker.

JavaScript SDK

The same API for Node.js and TypeScript.

API Reference

Every endpoint, parameter and response field.