# Schema (/academy/schema)



A **schema** is the promised shape. Not the data. The boxes the data must fit.

`email` is text. `age` is a number. `done` is true or false. Required or optional. That contract is what lets the [frontend](/academy/frontend-backend), the [API](/academy/api), and the [database](/academy/database) stop guessing.

**Two places you sign it**

At the door, [Zod](/academy/type-error) (or a cousin) checks the [JSON](/academy/json) that just arrived. Guilty until it matches. A string in the number box is a loud no — not a silent `undefined` on stage.

In the cabinet, the [ORM](/academy/orm) schema is the same promise in SQL. Add a column in TypeScript and forget the migration, and you get the classic hackathon bug: it works on your laptop because your file already has the field. It dies for the judge because theirs does not.

When someone says "we changed the schema," they mean they changed the form. Every old row has to live with that. That is bigger than changing one todo.

**Agents need fields, not a paragraph**

If you want an [agent](/academy/agent) to hand data to a tool, give it the schema first. "Fill these keys." Otherwise you get a friendly essay where you needed `{ title, done }`.

The [builder](/builder) already picked types. Keep them. Do not smuggle extra fields through because "it works on my machine." A [YAML](/academy/yaml) config and a JSON body can share a shape. The schema is how you notice when they don't.

**What this unlocks**

Shape first, then rows.

When the form and the payload disagree, you want the bounce in development — not in front of a judge.
