Extract Data from Video
Extract structured data from an online video's transcript using a custom schema.
Provide a video_url and a schema describing the fields to extract. Optionally include what_to_extract to guide the extraction.
Auto-transcription: For non-YouTube videos without an existing transcript (e.g. Instagram, TikTok, Facebook), the API automatically transcribes the video audio when transcribe is true (the default). YouTube videos rely on platform captions and cannot be auto-transcribed. Set transcribe=false to disable this behavior.
Schema format: Each field must have type and description. Supported types: String, Number, Boolean, Integer, Object, Array, Enum. Max 10 root fields, max 3 nesting levels.
Content-Type: Accepts application/json, YAML (application/yaml, application/x-yaml, text/yaml), or multipart/form-data. For multipart requests, send video_url as a form field and schema as either a JSON/YAML form value or an uploaded JSON/YAML file (for example, schema=@fact-check.yaml). If the uploaded schema file contains a full request body with a nested schema property, the nested schema is used and the form video_url takes precedence.
Token usage: Set include_usage=true to include prompt/completion token counts in the response.
Long videos: this endpoint is synchronous and holds the connection open for the whole transcription. For media longer than ~10 minutes use POST /extract/video/async instead, which returns a task_id and can call your webhook when it finishes. Media longer than 10 minutes is rejected here with video_too_long (HTTP 400). Send long media to the async endpoint, which has no cap. See https://docs.vidnavigator.com/guides/async-jobs
Extract structured data from an online video's transcript using a custom schema you define.
Overview
The extraction endpoint lets you pull structured, typed data from any video transcript by providing a JSON schema describing the fields you need. This is ideal for building automated pipelines that need consistent, machine-readable output from video content.
How It Works
- Provide a
video_urland aschemadefining the fields to extract - VidNavigator fetches the platform transcript when available
- For supported non-YouTube sources, it can auto-transcribe audio when no transcript exists
- VidNavigator runs AI extraction against your schema
- You receive structured JSON matching your schema definition, plus
video_info
Schema Rules
- Each field must have
typeanddescription - Supported types:
String,Number,Boolean,Integer,Object,Array,Enum - Maximum 10 root-level fields
- Maximum 3 nesting levels
You can also send the request body as YAML by setting Content-Type to application/x-yaml or text/yaml.
Automatic Transcription
The transcribe parameter controls whether VidNavigator should automatically fall back to speech-to-text when a transcript is not available.
transcribe=trueby default- applies to non-YouTube videos only
- useful for platforms like Instagram, TikTok, Facebook, X, and similar sources
- YouTube extraction relies on platform captions and does not support speech-to-text fallback through this endpoint
If you set transcribe=false, the request will fail when no transcript is available instead of triggering speech-to-text processing.
Synchronous or async?
The extraction itself is fast; the speech-to-text step in front of it is what takes time on long videos. This endpoint therefore comes in two modes, with the same request body and the same result:
| Mode | Endpoint | Media duration (with speech-to-text) | How you get the result |
|---|---|---|---|
| Synchronous | POST /extract/video | Up to 10 minutes | In the HTTP response |
| Async | POST /extract/video/async | Any length | Poll GET /extract/video/{task_id} or receive a webhook |
When transcribe is on and the video is longer than 10 minutes, the synchronous endpoint rejects it with 400 video_too_long. Use the async mode whenever the video may run past 10 minutes — it also works for short videos.
Example Usage
Basic Extraction
curl -X POST "https://api.vidnavigator.com/v1/extract/video" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"schema": {
"main_topics": {
"type": "Array",
"description": "List of main topics discussed",
"items": { "type": "String", "description": "A topic" }
},
"sentiment": {
"type": "Enum",
"description": "Overall sentiment of the video",
"enum": ["positive", "negative", "neutral"]
},
"key_takeaway": {
"type": "String",
"description": "The single most important takeaway"
}
}
}'With Extraction Guidance
Use what_to_extract to provide additional context to the AI about what to focus on:
curl -X POST "https://api.vidnavigator.com/v1/extract/video" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://youtube.com/watch?v=dQw4w9WgXcQ",
"what_to_extract": "Focus on product names and pricing mentioned in the video",
"schema": {
"products": {
"type": "Array",
"description": "Products mentioned in the video",
"items": {
"type": "Object",
"description": "A product",
"properties": {
"name": { "type": "String", "description": "Product name" },
"price": { "type": "String", "description": "Price if mentioned" }
}
}
}
},
"include_usage": true
}'Disable Auto-Transcription
Use transcribe=false when you want extraction to run only if a platform transcript already exists:
curl -X POST "https://api.vidnavigator.com/v1/extract/video" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://www.instagram.com/reel/example/",
"transcribe": false,
"schema": {
"main_claim": {
"type": "String",
"description": "Main claim made in the video"
}
}
}'Response Example
{
"status": "success",
"data": {
"main_topics": ["machine learning", "neural networks", "data preprocessing"],
"sentiment": "positive",
"key_takeaway": "Start with clean data before choosing a model architecture"
},
"video_info": {
"title": "Machine Learning Fundamentals",
"description": "An introduction to practical machine learning workflows.",
"thumbnail": "https://example.com/thumbnail.jpg",
"url": "https://youtube.com/watch?v=example123",
"channel": "AI Academy",
"duration": 4520.0,
"views": 152340,
"likes": 8100,
"published_date": "2026-03-05",
"keywords": ["machine learning", "ai", "data science"],
"category": "Education"
},
"usage": {
"prompt_tokens": 2150,
"completion_tokens": 85,
"total_tokens": 2235
}
}The usage field is only included when include_usage=true in the request. video_info is included in the response metadata.
Billing
- AI extraction consumes
analysis_requestunits in blocks of 15,000 total tokens - Formula:
ceil(total_tokens / 15000) - Examples:
14,000tokens ->1analysis_requestunit17,000tokens ->2analysis_requestunits31,000tokens ->3analysis_requestunits
- If
transcribe=truetriggers speech-to-text fallback, speech-to-text is charged separately astranscription_hourusage based on video/audio duration - Failed requests are not charged
- Set
include_usage: trueto receive ausageblock with the per-charge breakdown (theanalysis_requestentry carries a nestedtokensobject) - The async mode is billed exactly the same way
- A
video_too_longrejection on the synchronous endpoint still bills the metadata fetch that read the duration (standard_requestorresidential_request, not refunded), but notranscription_hourand noanalysis_request
Error Responses
| Status | error | Description |
|---|---|---|
400 | missing_parameter, request_body_required, invalid_schema, input_too_large | Invalid request or schema. |
400 | video_too_long | Speech-to-text is needed and the media is longer than 10 minutes. Use POST /extract/video/async. |
402 | limit_exceeded | Not enough credits. |
404 | video_not_found, video_unavailable, transcript_not_available | The video can't be found or accessed, or no transcript is available. |
500 | extraction_failed, transcription_failed, internal_server_error | Processing failed. Charges are reverted. |
503 | system_overload | Temporarily overloaded. Retry later. |
See Errors for the full list.
Use Cases
Data Pipelines
Build automated pipelines that extract consistent structured data from video content at scale
Content Cataloging
Automatically tag and categorize videos with custom taxonomies
Market Research
Extract product mentions, sentiment, and competitive insights from video reviews
Compliance Monitoring
Pull specific compliance-relevant data points from training or policy videos
API reference
ApiKeyAuthX-API-Key<token>API key authentication. Include your VidNavigator API key in the X-API-Key header.
- body
video_url*stringURL of the video to extract data from
urischema*Custom extraction schema defining the fields to extract. Max 10 root-level fields, max 3 nesting levels. Each field must have type and description.
what_to_extract?stringOptional guidance for what to extract from the transcript
transcribe?booleanWhen true, automatically transcribes the video audio if no platform transcript is available. Applies to non-YouTube videos only (Instagram, TikTok, Facebook, X, etc.).
trueinclude_usage?booleanWhen true, includes token usage statistics in the response
falseData extracted successfully
application/json- response
status?"success""success"data?Extracted data matching the provided schema. The shape of this object mirrors the input schema fields.
video_info?Video metadata (title, channel, duration, views, etc.). Only present for /extract/video requests.
file_info?File metadata (name, size, type, duration, etc.). Only present for /extract/file requests.
usage?Per-call usage, only present when include_usage=true: the charges (charges, total_credits, credits_remaining_after, waived) and the token counts (prompt_tokens, completion_tokens, total_tokens) in one object.
curl -X POST 'https://api.vidnavigator.com/v1/extract/video' \ -H 'Content-Type: application/json' \ -d '{ "video_url": "https://youtube.com/watch?v=dQw4w9WgXcQ", "schema": { "main_topics": { "type": "Array", "description": "List of main topics discussed", "items": { "type": "String", "description": "A topic" } }, "sentiment": { "type": "Enum", "description": "Overall sentiment of the video", "enum": [ "positive", "negative", "neutral" ] }, "key_takeaway": { "type": "String", "description": "The single most important takeaway" } }}'{ "status": "success", "data": {}, "video_info": { "title": "string", "description": "string", "thumbnail": "http://example.com", "url": "http://example.com", "channel": "string", "channel_url": "http://example.com", "duration": 0, "views": 0, "likes": 0, "published_date": "string", "keywords": [ "string" ], "category": "string", "available_languages": [ "string" ], "selected_language": "string", "carousel_info": { "total_items": 0, "video_count": 0, "image_count": 0, "selected_index": 0 } }, "file_info": { "id": "string", "name": "string", "size": 0, "type": "string", "duration": 0, "status": "pending", "created_at": "2019-08-24T14:15:22Z", "updated_at": "2019-08-24T14:15:22Z", "original_file_date": "2019-08-24T14:15:22Z", "has_transcript": true, "error_message": "string", "namespace_ids": [ "string" ], "namespaces": [ { "id": "string", "name": "string" } ] }, "usage": { "charges": [ { "service_type": "standard_request", "quantity": 0, "credits": 0, "waived": true, "credits_saved": 0, "tokens": { "prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0 } } ], "total_credits": 0, "waived": { "credits_saved": 0 } }}