# Asking for structured output: lists, tables, JSON
Paste this messy blob into ChatGPT: *"Sarah Lee, sarah@acme.io, marketing lead, joined March 2023. Then there's Raj Patel (raj.patel@acme.io) who runs sales, been here since 2021. Oh and Mia, our designer, mia.d@acme.io, started last fall."*
Now add one sentence: *"Turn this into a table with columns Name, Email, Role, Start Year."*
You get this back in seconds:
| Name | Email | Role | Start Year |
|------|-------|------|------------|
| Sarah Lee | sarah@acme.io | Marketing Lead | 2023 |
| Raj Patel | raj.patel@acme.io | Sales | 2021 |
| Mia | mia.d@acme.io | Designer | 2025 |
That is the whole lesson in a nutshell: if you want a specific shape, ask for that shape. The model will happily reorganize your text. It just needs to know the target.
By default, AI models reply in prose: paragraphs, explanations, friendly filler. That is fine for reading. It is terrible for *using*.
If you want to:
Each format is just a different container for the same information. Picking the right one saves you from copy-paste cleanup later.
The easiest structure. Good for steps, options, or short items.
> *"Give me 5 subject lines for a launch email. Bullet points, no explanations."*
Add "no explanations" or "just the list" to stop the model from padding each item with commentary.
Best when every item has the same fields. The magic move is naming your columns.
> *"Summarize these three laptops in a table. Columns: Model, Price, Battery Life, Weight."*
When you name columns, the model fills exactly those and nothing extra. If you do not name them, it guesses, and the result is messier.
CSV means "comma-separated values." It is plain text where each row is a line and commas separate the fields. It is the universal language of spreadsheets.
> *"Output the contact list as CSV with a header row."*
Name,Email,Role,Start Year
Sarah Lee,sarah@acme.io,Marketing Lead,2023
Raj Patel,raj.patel@acme.io,Sales,2021
Mia,mia.d@acme.io,Designer,2025Copy that, paste it into a .csv file (or straight into Google Sheets via File > Import), and you have a working spreadsheet.
JSON ("JavaScript Object Notation") is the format programs use to pass data around. You do not need to be a coder to recognize it: it is a set of labels and values wrapped in curly braces and square brackets.
> *"Output the same contacts as a JSON array of objects with keys: name, email, role, start_year."*
[
{ "name": "Sarah Lee", "email": "sarah@acme.io", "role": "Marketing Lead", "start_year": 2023 },
{ "name": "Raj Patel", "email": "raj.patel@acme.io", "role": "Sales", "start_year": 2021 },
{ "name": "Mia", "email": "mia.d@acme.io", "role": "Designer", "start_year": 2025 }
]You will reachreachThe number of unique people exposed to your message in a given period. Unlike impressions, reach counts each person once, no matter how often they see it.View full definition → for JSON when another tool needs to read the output: an automation in Zapier or Make, a script, or an app you are building.
If you want to learn what valid JSON actually looks like, the official JSON site has a clean one-page reference.
Models are good at structure, but vague requests get vague results. These phrases reliably tighten the output.
Name your fields. "Columns: Name, Email, Role" beats "make a table."
State the format explicitly. "Output as CSV." "Return valid JSON." "Use a markdown table."
Set the boundaries. "No explanation, just the table." "Do not add a summary." This kills the chatty intro and the "Let me know if you need anything else!" outro.
Handle missing data up front. "If a field is unknown, write N/A." Otherwise the model invents values or leaves ragged gaps.
Lock the structure when it matters. "Every object must have the same keys, even if empty." This prevents one row from secretly dropping a field.
Put together, a strong prompt looks like this:
> *"From the text below, extract every person. Return valid JSON: an array of objects with keys name, email, role, start_year. If a value is missing, use null. No commentary, JSON only."*
That prompt is boring on purpose. Boring prompts produce reliable structure.
Say you copied a page of event registrations into a chaotic paragraph. Here is the full move.
Step 1. Paste the messy text.
Step 2. Prompt:
> *"Extract all attendees as CSV. Header row, columns: Name, Company, Email, Ticket Type. If a field is missing, leave it blank. CSV only, no extra text."*
Step 3. Copy the result into a new Google Sheet (Paste, then Data > Split text to columns if needed, though importing CSV usually splits automatically).
Step 4. If a few rows look wrong, do not re-prompt the whole thing. Just say: *"Row 4 has the company in the email column, fix only that row."*
This loop (extract, eyeball, correct one thing) is faster than cleaning data by hand and far less error-prone than doing it in your head.
Knowledge check
1. According to the lesson, what is the single most important principle when you want a specific output format from an AI model?
2. In the laptop example, why does the lesson recommend naming your table columns (e.g., 'Columns: Model, Price, Battery Life, Weight')?
3. A colleague wants AI output that can be fed directly into another program. Based on the lesson's format guidance, which format should they request?
4. Select ALL correct answers. According to the lesson, when is a TABLE the appropriate structure to request?
Sélectionnez toutes les réponses correctes.
5. Select ALL correct answers about getting clean output from an AI model based on the lesson.
Sélectionnez toutes les réponses correctes.
If you are wiring AI into a program, you want output you can trust *every time*. In 2026, the big providers support a "structured output" or "JSON mode" feature that forces the model to return valid JSON matching a shape you define. No more parsing broken brackets.
Here is a minimal example using OpenAI's Python library. You describe the shape with a schemaschemaA schema is the formal blueprint that defines how data is structured, named, typed, and related within a database, file, or message.View full definition →, and the model is constrained to fit it.
from openai import OpenAI
client = OpenAI()
messy = "Sarah Lee, sarah@acme.io, marketing lead, joined 2023. Raj Patel raj.patel@acme.io runs sales since 2021."
response = client.chat.completions.create(
model="gpt-4.1",
messages=[
{"role": "system", "content": "Extract people as JSON."},
{"role": "user", "content": messy},
],
response_format={
"type": "json_schema",
"json_schema": {
"name": "contacts",
"schema": {
"type": "object",
"properties": {
"people": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {"type": "string"},
"email": {"type": "string"},
"role": {"type": "string"},
"start_year": {"type": "integer"}
},
"required": ["name", "email", "role", "start_year"]
}
}
},
"required": ["people"]
}
}
}
)
print(response.choices[0].message.content)The payoff: the output is guaranteed to be valid JSON with exactly those keys. Your next line of code can load it without crashing. Claude and Gemini offer equivalent features (tool/function calling and structured output modes), so the pattern carries across tools.
If you are not coding, you still get most of this benefit just by writing a precise prompt in the chat window. The APIAPIApplication Programming Interface: a standardised interface that lets applications communicate and exchange data without knowing each other's internal workings.View full definition → simply makes it bulletproof for repeated, automated use.
Structured Outputs with the OpenAI API
The model adds chatter around your table. Add "Output the table only, no text before or after."
Numbers come back as text (like "2,023" with a comma). Specify "start_year as a plain integer, no formatting."
Rows have inconsistent columns. Say "Every row must have all columns; use null for missing values."
The table is too wide to read. Ask it to flip: "Make it a vertical table with one attribute per row" for a single item, or split into two tables.
CSV breaks because a field contains a comma (like "Lee, Sarah"). Tell it: "Wrap any field containing a comma in double quotes." That is standard CSV behavior and spreadsheets expect it.
Think of yourself as handing the model a blank form. The clearer the form (named columns, stated format, rules for blanks), the better it fills it out. You are not hoping for good output. You are *specifying* it.
Once this clicks, you stop accepting walls of text. You start saying "as a table," "as CSV," "as JSON," and you get data you can actually use.
N/A, null, or empty), so you never get invented values.