# Schemas

A schema is a JSON Schema document describing exactly the object you want back. Our AI engine reads your selected inputs and returns one JSON object that conforms to it: no free-form text, no surprises in shape. Use one of our ready-made schemas, or send your own.

## Ready-made schemas

We maintain 32 predefined schemas for common video types. Pass a `schemaId` instead of an inline `schema` and we'll fill it, with no schema authoring on your side:

```json
POST /v1/extractions
{
  "url": "https://youtube.com/watch?v=...",
  "schemaId": "vidextract.predefined.recipe.v1"
}
```

Each links to its full field reference and raw JSON Schema. Browse them all at [/schemas](/schemas):

- [Recipe](/schemas/recipe): Ingredients, steps, times, and yields from any cooking video. `vidextract.predefined.recipe.v1`
- [Workout](/schemas/workout): Exercises, sets, reps, and timed holds from any fitness clip. `vidextract.predefined.workout.v1`
- [Product Review](/schemas/product-review): Verdict, specs, pros and cons from a review or unboxing. `vidextract.predefined.product_review.v1`
- [Travel Guide](/schemas/travel): Mappable stops, tips, and costs from a travel vlog. `vidextract.predefined.travel_itinerary.v1`
- [How-To](/schemas/howto): Ordered steps, tools, and gotchas from any tutorial. `vidextract.predefined.howto.v1`
- [Property Tour](/schemas/property): Price, rooms, and features from a real-estate walkthrough. `vidextract.predefined.property_tour.v1`
- [Music Video](/schemas/music): Song, artist, mood, and visual style from any music video. `vidextract.predefined.music_video.v1`
- [Sports Highlight](/schemas/sports): Teams, score, and key moments from a match recap. `vidextract.predefined.sports_highlight.v1`
- [Gaming Clip](/schemas/gaming): Game, players, and standout plays from a gaming or esports clip. `vidextract.predefined.gaming_clip.v1`
- [Outfit](/schemas/fashion): Every piece, brand, and the styling from a fashion clip. `vidextract.predefined.fashion_outfit.v1`
- [Podcast Episode](/schemas/podcast): Hosts, guests, topic-by-topic breakdown, takeaways, and quotes from any podcast. `vidextract.predefined.podcast.v1`
- [Book Summary](/schemas/book-summary): Core thesis, key lessons, named concepts, and the verdict from a book summary. `vidextract.predefined.book_summary.v1`
- [News Report](/schemas/news): Headline, the five Ws, key facts, people, organizations, and cited sources. `vidextract.predefined.news.v1`
- [Educational Explainer](/schemas/explainer): Key terms, ordered main points, examples, and takeaways from any explainer. `vidextract.predefined.explainer.v1`
- [Interview](/schemas/interview): Interviewer and guests, Q&A exchanges, revelations, and quotes. `vidextract.predefined.interview.v1`
- [Q&A / FAQ](/schemas/qanda): Every question paired with a clear self-contained answer, plus takeaways. `vidextract.predefined.qanda.v1`
- [Car Review](/schemas/car-review): The vehicle, its specs, how it drives, and the verdict from a car review. `vidextract.predefined.car_review.v1`
- [Coding Tutorial](/schemas/coding): What's built, the stack, ordered steps with code, concepts, and gotchas. `vidextract.predefined.coding.v1`
- [Beauty Tutorial](/schemas/beauty): Products, ordered steps, techniques, and warnings from a beauty tutorial. `vidextract.predefined.beauty.v1`
- [Art Tutorial](/schemas/art-tutorial): Subject, medium, materials, ordered steps, and techniques from an art tutorial. `vidextract.predefined.art_tutorial.v1`
- [Music Lesson](/schemas/music-lesson): Instrument, chords and scales taught, ordered steps, and practice guidance. `vidextract.predefined.music_lesson.v1`
- [Language Lesson](/schemas/language): Vocabulary and phrases with translations, grammar points, and study tips. `vidextract.predefined.language.v1`
- [Gardening Guide](/schemas/gardening): Plant-care steps, growing conditions, pests, and pro tips from a gardening video. `vidextract.predefined.gardening.v1`
- [Pet Training Guide](/schemas/pet-training): Target behavior, method, ordered steps, and troubleshooting from a training video. `vidextract.predefined.pet_training.v1`
- [Science Experiment](/schemas/science): Procedure, concepts, observation, explanation, and safety from a science demo. `vidextract.predefined.science.v1`
- [History Explainer](/schemas/history): Timeline of key events, figures, causes, and consequences from a history video. `vidextract.predefined.history.v1`
- [Conference Talk](/schemas/talk): Thesis, key points, takeaways, quotes, and predictions from any keynote or talk. `vidextract.predefined.talk.v1`
- [Personal Finance](/schemas/finance): Actionable money and investing advice: tips, action steps, and rules of thumb. `vidextract.predefined.finance.v1`
- [Cocktail Recipe](/schemas/cocktail): Ingredients, build steps, technique, glassware, and garnish from a drink video. `vidextract.predefined.cocktail.v1`
- [Restaurant Review](/schemas/restaurant): Per-dish verdicts and sentiment, ratings, highlights, and criticisms. `vidextract.predefined.restaurant.v1`
- [Guided Meditation](/schemas/meditation): Ordered phases, breathing patterns, affirmations, and visualizations. `vidextract.predefined.meditation.v1`
- [Motivational Speech](/schemas/motivation): Key points, memorable quotes, stories, call to action, and takeaways. `vidextract.predefined.motivation.v1`

## Custom schemas

Need a different shape? Send any JSON Schema inline as `schema` and the model fills it.

### The basics

Your schema must be a **top-level object**: a `"type": "object"` with a `properties` map. Each property gets a `type` (`string`, `number`, `integer`, `boolean`, `array`, `object`) and ideally a `description`. Descriptions are instructions to the AI, and they're the single biggest lever on extraction quality. List the fields that must always be present in `required`; arrays declare their element shape in `items`; fixed sets of values use `enum`.

## Rules for a well-behaved schema

- **Optional fields: leave them out of `required`.** Don't use type unions like `"type": ["string", "null"]`, which aren't supported. A field that isn't required is simply omitted when the video has nothing for it.
- **Enums are strings only.** Every value in an `enum` must be a string, paired with a single `"type": "string"`. No numbers, no `null` inside the enum list.
- **Keep it flat-ish.** One or two levels of nesting is fine; deeply nested structures degrade extraction quality. Prefer descriptive field names (`price_mentioned`, not `p`), because the AI reads them.
- **Advanced keywords don't steer, and aren't enforced.** `pattern`, `minItems`, `uniqueItems` and friends are stripped before the model sees them and are **not** checked afterwards, so treat them as documentation, not guarantees. This is deliberate: enforcing a minimum count would just pressure the model to invent data to hit it. A clear `description` is the real lever, and if the video genuinely has nothing to extract you'll get `outcome: "no_match"` on the result ([more](/docs/extractions)) rather than a padded object.
- **Want a specific output language?** Say so in the field descriptions ("in English"). The AI understands the video's original language either way.

## Worked example: a product-review schema

Say you're extracting structured reviews from tech videos. A schema like this:

```json
{
  "type": "object",
  "properties": {
    "product_name": {
      "type": "string",
      "description": "Exact name of the product being reviewed"
    },
    "brand": {
      "type": "string",
      "description": "Brand or manufacturer, if mentioned"
    },
    "verdict": {
      "type": "string",
      "enum": ["recommended", "mixed", "not_recommended"],
      "description": "The reviewer's overall verdict"
    },
    "rating_out_of_10": {
      "type": "integer",
      "minimum": 0,
      "maximum": 10,
      "description": "Score implied or stated by the reviewer"
    },
    "pros": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Things the reviewer liked, one short phrase each"
    },
    "cons": {
      "type": "array",
      "items": { "type": "string" },
      "description": "Things the reviewer disliked"
    },
    "price_mentioned": {
      "type": "string",
      "description": "Price as stated in the video, with currency"
    }
  },
  "required": ["product_name", "verdict", "pros", "cons"]
}
```

### What comes back

Running it against a review video returns one object in exactly that shape. Optional fields (`brand`, `rating_out_of_10`, `price_mentioned`) appear only when the video actually contains them:

```json
{
  "product_name": "AeroPress Clear",
  "brand": "AeroPress",
  "verdict": "recommended",
  "rating_out_of_10": 8,
  "pros": [
    "Brews in under two minutes",
    "Easy to clean",
    "Durable Tritan plastic"
  ],
  "cons": [
    "More expensive than the original",
    "Stains over time"
  ],
  "price_mentioned": "$49.95"
}
```

Tip: start with transcript + comments as inputs. It's the cheapest combination and covers most schemas. Add audio or full video analysis when the answer is only on screen or in the delivery.

## Pairing a prompt with your schema

A schema and its prompt work as a pair: the **schema** fixes the output shape, and an optional **`prompt`** tells the model *how to read the video into that shape*: source priority (on-screen text vs. spoken vs. description), what to omit rather than guess, and the pitfalls specific to your content. Field `description`s remain the biggest quality lever, but a prompt captures the cross-field judgment calls a per-field description can't.

Every ready-made schema ships with a tuned prompt; pass your own `prompt` to override it, or to pair one with an inline `schema`:

```json
POST /v1/extractions
{
  "url": "https://youtube.com/watch?v=...",
  "schema": { "type": "object", "properties": { "dish": { "type": "string" } }, "required": ["dish"] },
  "prompt": "Read the recipe from what the creator actually adds, not alternatives they only mention. Prefer on-screen ingredient cards over spoken asides. Never invent quantities."
}
```

The prompt is capped at 20KB and is part of the cache key, so editing it triggers a fresh run instead of reusing a cached result. It's ignored on download-only runs (no schema).
