Designing a Taxonomy for Narrative Metadata

Your taxonomy categories directly affect how reliably Narrative Metadata can classify your videos. Unclear or overlapping categories lead to inconsistent results, while distinct, well-documented categories improve accuracy.

This tutorial covers how to design a taxonomy and upload it programmatically using Python.

Structuring Your Taxonomy

Each taxonomy category requires three components:

ComponentPurposeExample
NameA concise identifier for the category”Tutorial”
DescriptionA detailed definition that guides classification”Step-by-step instructional content showing how to complete a task or learn a skill”
ExamplesRepresentative content that exemplifies the category[“software walkthrough”, “cooking demonstration”, “DIY project guide”]

Organize your categories in a CSV file with columns for metadata_type, name, description, and examples. The metadata_type must be one of: format, genre, mood, or subject.

Why taxonomy design matters

Overlapping or vague categories cause inconsistent results. Keep categories distinct—if content could fit two categories, consider merging them.

Example Taxonomy CSV

Here’s a sample taxonomy for classifying TV and entertainment content. This CSV defines categories across all four dimensions—format, genre, mood, and subject:

1metadata_type,name,description,examples
2format,Scripted Comedy Series,"An ongoing series that uses humor and comedic storytelling to entertain audiences episode by episode","[""Friends"", ""The Simpsons"", ""Schitt's Creek"", ""Abbott Elementary""]"
3format,Limited Series & Prestige TV,"A short, self-contained series with a high production budget and cinematic feel, typically wrapping up in one season","[""Chernobyl"", ""The White Lotus"", ""Squid Game"", ""Mare of Easttown""]"
4format,Scripted Drama Series,"An ongoing fictional series with serious storytelling, developed characters, and plots that build over multiple episodes","[""Breaking Bad"", ""Grey's Anatomy"", ""Succession"", ""Dark""]"
5format,Reality & Unscripted,"Non-fiction programming that follows real people, events, or competitions without a scripted storyline","[""Survivor"", ""The Bachelor"", ""Making a Murderer"", ""The Great British Bake Off""]"
6format,Feature Film,"A full-length standalone movie intended for theatrical release or streaming","[""Parasite"", ""Top Gun: Maverick"", ""Everything Everywhere All at Once"", ""RRR""]"
7format,Documentary & Docuseries,"Factual content that explores real people, events, or topics in depth, either as a single film or across multiple episodes","[""Tiger King"", ""Free Solo"", ""The Last Dance"", ""13th""]"
8genre,Comedy,"Content that entertains through humor, funny situations, and lighthearted storytelling","[""Ted Lasso"", ""What We Do in the Shadows"", ""Fleabag"", ""Brooklyn Nine-Nine""]"
9genre,Horror & Thriller,"Content meant to scare, unsettle, or keep audiences on edge through suspense, fear, or shocking twists","[""Get Out"", ""The Haunting of Hill House"", ""Train to Busan"", ""Hereditary""]"
10genre,Drama,"Serious storytelling focused on real human emotions, relationships, and life challenges","[""Succession"", ""Pose"", ""Squid Game"", ""Downton Abbey""]"
11genre,Action & Adventure,"Fast-paced content driven by physical conflict, daring feats, and high-energy sequences","[""Mad Max: Fury Road"", ""John Wick"", ""Money Heist"", ""The Witcher""]"
12genre,Science Fiction & Fantasy,"Imaginative storytelling set in invented worlds, the future, or situations involving technology, magic, or the unknown","[""Dune"", ""Severance"", ""The Mandalorian"", ""His Dark Materials""]"
13mood,Sinister Tension,"A creeping sense of dread or unease where something feels dangerously wrong beneath the surface","[""Mindhunter"", ""Hannibal"", ""The Fall"", ""Ozark""]"
14mood,Warm Nostalgia,"A gentle, bittersweet feeling of longing for the past — comforting yet tinged with the passage of time","[""The Wonder Years"", ""This Is Us"", ""Stranger Things"", ""Call the Midwife""]"
15mood,Stark Despair,"A heavy, hopeless emotional weight where characters or situations feel overwhelmed by loss or futility","[""The Leftovers"", ""Mare of Easttown"", ""The Wire"", ""Requiem for a Dream""]"
16mood,Lighthearted Comedy,"A breezy, fun tone that keeps things playful and low-stakes, designed purely to entertain and amuse","[""Ted Lasso"", ""Abbott Elementary"", ""The Good Place"", ""Schitt's Creek""]"
17mood,Surreal & Dreamlike,"A disorienting, otherworldly quality where the boundaries of reality blur and logic gives way to imagination","[""Twin Peaks"", ""Maniac"", ""The OA"", ""Legion""]"
18subject,Romance & Emotional Turmoil,"Stories centered on love, relationships, and the highs and lows that come with deep emotional connection","[""Normal People"", ""Bridgerton"", ""Fleabag"", ""Outlander""]"
19subject,Heroic & Epic Conflicts,"Stories about courage, sacrifice, and the struggle between good and evil on a large scale","[""Game of Thrones"", ""The Boys"", ""Avatar: The Last Airbender"", ""Shogun""]"
20subject,Family & Relationships,"Stories exploring how people connect, clash, and grow through bonds with family, friends, or community","[""This Is Us"", ""Succession"", ""Parenthood"", ""The Bear""]"
21subject,Crime & Justice,"Stories involving criminal acts, investigations, moral gray areas, and the pursuit of right and wrong","[""The Wire"", ""True Detective"", ""Better Call Saul"", ""Broadchurch""]"
22subject,Identity & Self-Discovery,"Stories about characters figuring out who they are, where they belong, and what they stand for","[""Pose"", ""Euphoria"", ""Master of None"", ""Feel Good""]"

Save your taxonomy as a CSV file (e.g., taxonomy.csv) before running the upload script.

Uploading Your Taxonomy with Python

The following Python script reads your taxonomy CSV and uploads each category to the Narrative Metadata API. This automates what would otherwise be repetitive manual API calls.

Prerequisites

Before running the script, you’ll need:

  • A Coactive API token (see API Authentication)
  • Your dataset ID
  • The requests library (pip install requests)

Complete Upload Script

1import csv
2import json
3import requests
4
5# Configuration
6API_TOKEN = "your_api_token_here"
7API_BASE_URL = "https://api.coactive.ai"
8TAXONOMY_CSV_PATH = "taxonomy.csv"
9
10def upload_taxonomy_category(metadata_type: str, name: str, description: str, examples: list[str]) -> dict:
11 """
12 Upload a single taxonomy category to the Narrative Metadata API.
13
14 Args:
15 metadata_type: One of 'format', 'genre', 'mood', or 'subject'
16 name: Category name (e.g., "Tutorial")
17 description: Detailed category description
18 examples: List of representative examples
19
20 Returns:
21 API response as a dictionary
22 """
23 url = f"{API_BASE_URL}/api/v0/video-narrative-metadata/metadata"
24
25 headers = {
26 "Authorization": f"Bearer {API_TOKEN}",
27 "Content-Type": "application/json"
28 }
29
30 payload = {
31 "metadata_type": metadata_type,
32 "name": name,
33 "description": description,
34 "examples": examples
35 }
36
37 response = requests.post(url, headers=headers, json=payload)
38 response.raise_for_status()
39 return response.json()
40
41
42def load_and_upload_taxonomy(csv_path: str) -> None:
43 """
44 Read taxonomy categories from a CSV file and upload each to the API.
45
46 Expected CSV columns: metadata_type, name, description, examples
47 The 'examples' column should contain a JSON-formatted list of strings.
48 """
49 with open(csv_path, "r", encoding="utf-8") as file:
50 reader = csv.DictReader(file)
51
52 for row in reader:
53 metadata_type = row["metadata_type"]
54 name = row["name"]
55 description = row["description"]
56
57 # Parse the examples column as JSON
58 examples = json.loads(row["examples"])
59
60 print(f"Uploading {metadata_type} category: {name}")
61
62 try:
63 result = upload_taxonomy_category(
64 metadata_type=metadata_type,
65 name=name,
66 description=description,
67 examples=examples
68 )
69 print(f" ✓ Successfully created: {result}")
70 except requests.exceptions.HTTPError as e:
71 print(f" ✗ Failed to create '{name}': {e}")
72
73
74if __name__ == "__main__":
75 print("Starting taxonomy upload...")
76 load_and_upload_taxonomy(TAXONOMY_CSV_PATH)
77 print("Taxonomy upload complete!")

How the Script Works

  1. Configuration: Set your API token and the path to your taxonomy CSV file.
  2. upload_taxonomy_category(): Makes a POST request to /api/v0/video-narrative-metadata/metadata with the category details.
  3. load_and_upload_taxonomy(): Reads the CSV file row by row, parses the JSON-formatted examples column, and calls the upload function for each category.
  4. Error handling: The script continues processing remaining categories even if one fails.

Running the Script

$# Install the requests library if needed
$pip install requests
$
$# Run the upload script
$python upload_taxonomy.py

Expected output:

Starting taxonomy upload...
Uploading format category: Scripted Comedy Series
✓ Successfully created: {'item': {'metadata_type': 'format', 'name': 'Scripted Comedy Series', ...}}
Uploading format category: Limited Series & Prestige TV
✓ Successfully created: {'item': {'metadata_type': 'format', 'name': 'Limited Series & Prestige TV', ...}}
...
Taxonomy upload complete!

Best Practices for Taxonomy Design

Keep Categories Distinct

Avoid categories that could reasonably describe the same content. If you’re unsure whether two categories overlap, try listing five examples for each—if any example fits both categories, consider merging them.

Write Descriptive Definitions

The description field helps the model understand what to look for. Include:

  • The defining characteristics of the category
  • What distinguishes it from similar categories
  • The emotional or narrative qualities to match

Use Representative Examples

Choose examples that clearly belong to the category and are recognizable. Specific, concrete descriptions work better than abstract or vague terms.

Start with Fewer Categories

Begin with 5–10 categories per dimension. You can always add more later, but starting with too many granular categories often leads to inconsistent classification.

Next Steps

After uploading your taxonomy, you’re ready to classify videos:

  1. Generate captions for your videos using the caption-keyframes endpoint
  2. Classify videos against your taxonomy categories
  3. Persist results as metadata for SQL queries and search

See the Narrative Metadata guide for the complete classification workflow.