curl --request POST \
--url https://api.vidnavigator.com/v1/extract/file \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"file_id": "<string>",
"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"
}
},
"what_to_extract": "Extract action items and deadlines from this meeting",
"include_usage": false
}
'import requests
url = "https://api.vidnavigator.com/v1/extract/file"
payload = {
"file_id": "<string>",
"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"
}
},
"what_to_extract": "Extract action items and deadlines from this meeting",
"include_usage": False
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
file_id: '<string>',
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'}
},
what_to_extract: 'Extract action items and deadlines from this meeting',
include_usage: false
})
};
fetch('https://api.vidnavigator.com/v1/extract/file', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vidnavigator.com/v1/extract/file",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'file_id' => '<string>',
'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'
]
],
'what_to_extract' => 'Extract action items and deadlines from this meeting',
'include_usage' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vidnavigator.com/v1/extract/file"
payload := strings.NewReader("{\n \"file_id\": \"<string>\",\n \"schema\": {\n \"main_topics\": {\n \"type\": \"Array\",\n \"description\": \"List of main topics discussed\",\n \"items\": {\n \"type\": \"String\",\n \"description\": \"A topic\"\n }\n },\n \"sentiment\": {\n \"type\": \"Enum\",\n \"description\": \"Overall sentiment of the video\",\n \"enum\": [\n \"positive\",\n \"negative\",\n \"neutral\"\n ]\n },\n \"key_takeaway\": {\n \"type\": \"String\",\n \"description\": \"The single most important takeaway\"\n }\n },\n \"what_to_extract\": \"Extract action items and deadlines from this meeting\",\n \"include_usage\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vidnavigator.com/v1/extract/file")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"file_id\": \"<string>\",\n \"schema\": {\n \"main_topics\": {\n \"type\": \"Array\",\n \"description\": \"List of main topics discussed\",\n \"items\": {\n \"type\": \"String\",\n \"description\": \"A topic\"\n }\n },\n \"sentiment\": {\n \"type\": \"Enum\",\n \"description\": \"Overall sentiment of the video\",\n \"enum\": [\n \"positive\",\n \"negative\",\n \"neutral\"\n ]\n },\n \"key_takeaway\": {\n \"type\": \"String\",\n \"description\": \"The single most important takeaway\"\n }\n },\n \"what_to_extract\": \"Extract action items and deadlines from this meeting\",\n \"include_usage\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vidnavigator.com/v1/extract/file")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"file_id\": \"<string>\",\n \"schema\": {\n \"main_topics\": {\n \"type\": \"Array\",\n \"description\": \"List of main topics discussed\",\n \"items\": {\n \"type\": \"String\",\n \"description\": \"A topic\"\n }\n },\n \"sentiment\": {\n \"type\": \"Enum\",\n \"description\": \"Overall sentiment of the video\",\n \"enum\": [\n \"positive\",\n \"negative\",\n \"neutral\"\n ]\n },\n \"key_takeaway\": {\n \"type\": \"String\",\n \"description\": \"The single most important takeaway\"\n }\n },\n \"what_to_extract\": \"Extract action items and deadlines from this meeting\",\n \"include_usage\": false\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {},
"video_info": {
"title": "<string>",
"description": "<string>",
"thumbnail": "<string>",
"url": "<string>",
"channel": "<string>",
"channel_url": "<string>",
"duration": 123,
"views": 123,
"likes": 123,
"published_date": "<string>",
"keywords": [
"<string>"
],
"category": "<string>",
"available_languages": [
"<string>"
],
"selected_language": "<string>",
"carousel_info": {
"total_items": 123,
"video_count": 123,
"image_count": 123,
"selected_index": 123
}
},
"file_info": {
"id": "<string>",
"name": "<string>",
"size": 123,
"type": "<string>",
"duration": 123,
"status": "pending",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"original_file_date": "2023-11-07T05:31:56Z",
"has_transcript": true,
"error_message": "<string>",
"namespace_ids": [
"<string>"
],
"namespaces": [
{
"id": "<string>",
"name": "<string>"
}
]
},
"usage": {
"charges": [
{
"service_type": "standard_request",
"quantity": 123,
"credits": 123,
"waived": true,
"credits_saved": 123,
"tokens": {
"prompt_tokens": 123,
"completion_tokens": 123,
"total_tokens": 123
}
}
],
"total_credits": 123,
"waived": {
"credits_saved": 123
}
}
}{
"status": "error",
"error": "missing_parameter",
"message": "<string>"
}{
"status": "error",
"error": "limit_exceeded",
"message": "<string>"
}{
"status": "error",
"error": "access_denied",
"message": "<string>"
}{
"status": "error",
"error": "file_not_found",
"message": "<string>"
}{
"status": "error",
"error": "metadata_fetch_failed",
"message": "<string>"
}{
"status": "error",
"error": "system_overload",
"message": "<string>",
"retry_after_seconds": 123,
"charge_user": true
}Extract Data from File
Extract structured data from an uploaded file’s transcript using a custom schema.
Provide a file_id and a schema describing the fields to extract. The file must be processed and have a transcript available. Optionally include what_to_extract to guide the extraction.
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 file_id as a form field and schema as either a JSON/YAML form value or an uploaded JSON/YAML file. If the uploaded schema file contains a full request body with a nested schema property, the nested schema is used and the form file_id takes precedence.
Token usage: Set include_usage=true to include prompt/completion token counts in the response.
Billing: Each extraction consumes at least 1 analysis credit. For longer transcripts, billing scales as ceil(total_tokens / 15000) credits. All charges are reverted if the request fails.
curl --request POST \
--url https://api.vidnavigator.com/v1/extract/file \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"file_id": "<string>",
"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"
}
},
"what_to_extract": "Extract action items and deadlines from this meeting",
"include_usage": false
}
'import requests
url = "https://api.vidnavigator.com/v1/extract/file"
payload = {
"file_id": "<string>",
"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"
}
},
"what_to_extract": "Extract action items and deadlines from this meeting",
"include_usage": False
}
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
file_id: '<string>',
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'}
},
what_to_extract: 'Extract action items and deadlines from this meeting',
include_usage: false
})
};
fetch('https://api.vidnavigator.com/v1/extract/file', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.vidnavigator.com/v1/extract/file",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'file_id' => '<string>',
'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'
]
],
'what_to_extract' => 'Extract action items and deadlines from this meeting',
'include_usage' => false
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.vidnavigator.com/v1/extract/file"
payload := strings.NewReader("{\n \"file_id\": \"<string>\",\n \"schema\": {\n \"main_topics\": {\n \"type\": \"Array\",\n \"description\": \"List of main topics discussed\",\n \"items\": {\n \"type\": \"String\",\n \"description\": \"A topic\"\n }\n },\n \"sentiment\": {\n \"type\": \"Enum\",\n \"description\": \"Overall sentiment of the video\",\n \"enum\": [\n \"positive\",\n \"negative\",\n \"neutral\"\n ]\n },\n \"key_takeaway\": {\n \"type\": \"String\",\n \"description\": \"The single most important takeaway\"\n }\n },\n \"what_to_extract\": \"Extract action items and deadlines from this meeting\",\n \"include_usage\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.vidnavigator.com/v1/extract/file")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"file_id\": \"<string>\",\n \"schema\": {\n \"main_topics\": {\n \"type\": \"Array\",\n \"description\": \"List of main topics discussed\",\n \"items\": {\n \"type\": \"String\",\n \"description\": \"A topic\"\n }\n },\n \"sentiment\": {\n \"type\": \"Enum\",\n \"description\": \"Overall sentiment of the video\",\n \"enum\": [\n \"positive\",\n \"negative\",\n \"neutral\"\n ]\n },\n \"key_takeaway\": {\n \"type\": \"String\",\n \"description\": \"The single most important takeaway\"\n }\n },\n \"what_to_extract\": \"Extract action items and deadlines from this meeting\",\n \"include_usage\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.vidnavigator.com/v1/extract/file")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"file_id\": \"<string>\",\n \"schema\": {\n \"main_topics\": {\n \"type\": \"Array\",\n \"description\": \"List of main topics discussed\",\n \"items\": {\n \"type\": \"String\",\n \"description\": \"A topic\"\n }\n },\n \"sentiment\": {\n \"type\": \"Enum\",\n \"description\": \"Overall sentiment of the video\",\n \"enum\": [\n \"positive\",\n \"negative\",\n \"neutral\"\n ]\n },\n \"key_takeaway\": {\n \"type\": \"String\",\n \"description\": \"The single most important takeaway\"\n }\n },\n \"what_to_extract\": \"Extract action items and deadlines from this meeting\",\n \"include_usage\": false\n}"
response = http.request(request)
puts response.read_body{
"status": "success",
"data": {},
"video_info": {
"title": "<string>",
"description": "<string>",
"thumbnail": "<string>",
"url": "<string>",
"channel": "<string>",
"channel_url": "<string>",
"duration": 123,
"views": 123,
"likes": 123,
"published_date": "<string>",
"keywords": [
"<string>"
],
"category": "<string>",
"available_languages": [
"<string>"
],
"selected_language": "<string>",
"carousel_info": {
"total_items": 123,
"video_count": 123,
"image_count": 123,
"selected_index": 123
}
},
"file_info": {
"id": "<string>",
"name": "<string>",
"size": 123,
"type": "<string>",
"duration": 123,
"status": "pending",
"created_at": "2023-11-07T05:31:56Z",
"updated_at": "2023-11-07T05:31:56Z",
"original_file_date": "2023-11-07T05:31:56Z",
"has_transcript": true,
"error_message": "<string>",
"namespace_ids": [
"<string>"
],
"namespaces": [
{
"id": "<string>",
"name": "<string>"
}
]
},
"usage": {
"charges": [
{
"service_type": "standard_request",
"quantity": 123,
"credits": 123,
"waived": true,
"credits_saved": 123,
"tokens": {
"prompt_tokens": 123,
"completion_tokens": 123,
"total_tokens": 123
}
}
],
"total_credits": 123,
"waived": {
"credits_saved": 123
}
}
}{
"status": "error",
"error": "missing_parameter",
"message": "<string>"
}{
"status": "error",
"error": "limit_exceeded",
"message": "<string>"
}{
"status": "error",
"error": "access_denied",
"message": "<string>"
}{
"status": "error",
"error": "file_not_found",
"message": "<string>"
}{
"status": "error",
"error": "metadata_fetch_failed",
"message": "<string>"
}{
"status": "error",
"error": "system_overload",
"message": "<string>",
"retry_after_seconds": 123,
"charge_user": true
}Overview
Extract structured data from files you have previously uploaded to your VidNavigator library. The file must be fully processed and have a transcript available.How It Works
- Provide a
file_idand aschemadescribing the structured fields you want - VidNavigator reads the transcript from the uploaded file
- VidNavigator runs AI extraction against your schema
- You receive structured JSON matching your schema definition, plus
file_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
Content-Type to application/x-yaml or text/yaml.transcribe parameter. It works only on files that already have a transcript available.Example Usage
curl -X POST "https://api.vidnavigator.com/v1/extract/file" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"file_id": "file_abc123",
"schema": {
"action_items": {
"type": "Array",
"description": "Action items and tasks mentioned in the meeting",
"items": {
"type": "Object",
"description": "An action item",
"properties": {
"task": { "type": "String", "description": "The task description" },
"assignee": { "type": "String", "description": "Person assigned" },
"deadline": { "type": "String", "description": "Deadline if mentioned" }
}
}
},
"decisions_made": {
"type": "Array",
"description": "Key decisions made during the meeting",
"items": { "type": "String", "description": "A decision" }
}
},
"what_to_extract": "Extract action items and deadlines from this meeting",
"include_usage": true
}'
import requests
url = "https://api.vidnavigator.com/v1/extract/file"
headers = {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"file_id": "file_abc123",
"schema": {
"action_items": {
"type": "Array",
"description": "Action items and tasks mentioned in the meeting",
"items": {
"type": "Object",
"description": "An action item",
"properties": {
"task": {"type": "String", "description": "The task description"},
"assignee": {"type": "String", "description": "Person assigned"},
"deadline": {"type": "String", "description": "Deadline if mentioned"}
}
}
},
"decisions_made": {
"type": "Array",
"description": "Key decisions made during the meeting",
"items": {"type": "String", "description": "A decision"}
}
},
"what_to_extract": "Extract action items and deadlines from this meeting"
}
response = requests.post(url, headers=headers, json=data)
result = response.json()
const response = await fetch('https://api.vidnavigator.com/v1/extract/file', {
method: 'POST',
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
file_id: 'file_abc123',
schema: {
action_items: {
type: 'Array',
description: 'Action items and tasks mentioned in the meeting',
items: {
type: 'Object',
description: 'An action item',
properties: {
task: { type: 'String', description: 'The task description' },
assignee: { type: 'String', description: 'Person assigned' },
deadline: { type: 'String', description: 'Deadline if mentioned' }
}
}
},
decisions_made: {
type: 'Array',
description: 'Key decisions made during the meeting',
items: { type: 'String', description: 'A decision' }
}
},
what_to_extract: 'Extract action items and deadlines from this meeting'
})
});
const result = await response.json();
Response Example
{
"status": "success",
"data": {
"action_items": [
{
"task": "Update the product roadmap with Q2 priorities",
"assignee": "Sarah",
"deadline": "Friday"
},
{
"task": "Schedule customer interviews for user research",
"assignee": "Mike",
"deadline": "next week"
}
],
"decisions_made": [
"Proceed with option B for the pricing model",
"Delay the mobile app launch to Q3"
]
},
"file_info": {
"id": "file_abc123",
"name": "weekly-product-meeting.mp4",
"size": 248517632,
"type": "video/mp4",
"duration": 3720.0,
"status": "completed",
"created_at": "2026-04-10T09:30:00Z",
"updated_at": "2026-04-10T09:36:12Z",
"has_transcript": true,
"namespace_ids": ["ns_team_notes"],
"namespaces": [
{
"id": "ns_team_notes",
"name": "Team Notes"
}
]
},
"usage": {
"prompt_tokens": 3200,
"completion_tokens": 120,
"total_tokens": 3320
}
}
usage field is only included when include_usage=true in the request. file_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
- There is no speech-to-text billing on this endpoint
- Failed requests are not charged
- Set
include_usage: trueto receive ausageblock with the per-charge breakdown (theanalysis_requestentry carries a nestedtokensobject)
Authorizations
API key authentication. Include your VidNavigator API key in the X-API-Key header.
Body
ID of the uploaded file to extract data from
Custom extraction schema defining the fields to extract. Max 10 root-level fields, max 3 nesting levels. Each field must have type and description.
Show child attributes
Show child attributes
{
"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"
}
}
Optional guidance for what to extract from the transcript
"Extract action items and deadlines from this meeting"
When true, includes token usage statistics in the response
Response
Data extracted successfully
success Extracted data matching the provided schema. The shape of this object mirrors the input schema fields.
Video metadata (title, channel, duration, views, etc.). Only present for /extract/video requests.
Show child attributes
Show child attributes
File metadata (name, size, type, duration, etc.). Only present for /extract/file requests.
Show child attributes
Show child attributes
Per-call billing + LLM token usage. Only present when include_usage=true. For /extract/*, the block carries the credit-charge fields (charges, total_credits, credits_remaining_after, waived) AND the LLM token fields (prompt_tokens, completion_tokens, total_tokens) in a single object.
Show child attributes
Show child attributes

