Importing TV Spots (JSON)
This guide covers the JSON format for TV spot scripts and the import_tvspot management command for bulk creation.
JSON Format
TV spot scripts use a flat JSON structure with top-level metadata and an array of script rows.
Required Fields
Field |
Type |
Description |
|---|---|---|
|
string |
Client organization name |
|
string |
Campaign or script title |
|
integer |
Total spot duration in seconds (must be positive) |
|
string |
Unique tracking ID (e.g., |
|
array |
Array of script row objects (at least one required) |
Optional Fields
Field |
Type |
Description |
|---|---|---|
|
string |
Brand name (for display purposes) |
|
string |
Language code (e.g., |
|
string |
Free-text notes or production context |
Script Row Fields
Each script row represents one shot or scene:
Field |
Type |
Description |
|---|---|---|
|
string |
Visual description: shot composition, talent direction, settings, supers. Required, non-empty. |
|
string |
Audio content: voiceover, music cues, SFX, dialogue. Required, non-empty. |
|
string |
Shot identifier (e.g., |
|
string |
Timecode in |
|
float |
Shot duration in seconds (optional) |
Example JSON
{
"client_name": "Acme Corporation",
"brand_name": "Acme Energy Drink",
"script_title": "Morning Boost 30s",
"total_runtime_seconds": 30,
"job_id": "ACME-2024-001",
"language": "en-US",
"notes": "Q1 2024 campaign launch spot",
"script_rows": [
{
"shot_number": "01",
"timecode_start": "00:00:00:00",
"duration_seconds": 3.0,
"visual_text": "Wide shot: Urban apartment, early morning. Sunlight streaming through windows. TALENT (30s, professional) wakes up groggy, reaches for alarm clock.",
"audio_text": "SFX: Alarm buzzing\nMUSIC: Soft, building instrumental"
},
{
"shot_number": "02",
"timecode_start": "00:00:03:00",
"duration_seconds": 4.0,
"visual_text": "Medium shot: Kitchen counter. TALENT opens refrigerator, pulls out ACME ENERGY DRINK can. Product hero shot with condensation.",
"audio_text": "SFX: Refrigerator opening, can crack\nMUSIC: Energy builds"
},
{
"shot_number": "03",
"timecode_start": "00:00:07:00",
"duration_seconds": 3.0,
"visual_text": "Close-up: TALENT drinks. Expression transforms from tired to energized.",
"audio_text": "VO: \"Acme Energy. The boost you need.\"\nMUSIC: Peak energy"
}
]
}
A complete 8-row example is available at data/example_tvspot.json.
The import_tvspot Command
Usage
# Import a TV spot
uv run manage.py import_tvspot path/to/spot.json
# Validate without creating records
uv run manage.py import_tvspot path/to/spot.json --dry-run
What the Command Does
Validates the JSON — checks required fields, types, and script row structure
Checks for duplicates — ensures the
job_iddoesn’t already existCreates records in a single database transaction:
One Campaign (from top-level metadata)
One origin VideoAdUnit (code
ORIGIN, linked to the campaign)One AdUnitScriptRow per script row (linked to the origin ad unit)
Resolves the language — looks up the
languagecode in the database (requires reference data to be imported first)
Prerequisites
Before importing, ensure reference data is loaded:
uv run manage.py import_reference_data
This populates the Language table that the import command references.
Validation Rules
The command validates the following:
All required top-level fields are present
script_rowsis a non-empty arraytotal_runtime_secondsis a positive integerEach script row has non-empty
visual_textandaudio_textjob_idis unique (no existing campaign with the same ID)languagecode exists in the database
Dry Run Output
Reading TV spot from: data/example_tvspot.json
DRY RUN - validating only
✓ JSON validation passed
TV Spot Details:
Client: Acme Corporation
Title: Morning Boost 30s
TRT: 30s
Job ID: ACME-2024-001
Script rows: 8
Validation complete (dry run)
Import Output
Reading TV spot from: data/example_tvspot.json
✓ JSON validation passed
TV Spot Details:
Client: Acme Corporation
Title: Morning Boost 30s
TRT: 30s
Job ID: ACME-2024-001
Script rows: 8
✓ Created TvSpot #1
✓ Created TvSpotVersion #1 (origin, language=en-US)
✓ Created 8 script rows
============================================================
Import Complete!
TV Spot ID: 1
Version ID: 1
============================================================
Error Handling
Error |
Cause |
|---|---|
|
The specified path doesn’t exist |
|
File contains malformed JSON |
|
A required top-level field is absent |
|
A script row is missing its visual description |
|
A campaign with the same |
|
The specified language code hasn’t been imported. Run |
All imports are wrapped in a database transaction — if any step fails, no records are created.
After Import
Once a campaign is imported:
View it under TV Spots > Campaigns
The origin ad unit and script rows are ready
Create adaptation ad units targeting specific markets (see Origin & Adaptation Ad Units)
Generate storyboards to visualize scripts (see Storyboard Generation)