22 Jul 2026
Getting reliable structured output from Claude for product SEO
I've got a client who sells antiques and collectibles online, diecast models, model railway pieces, vinyl records, automotive memorabilia, that kind of thing. Products come in from bulk supplier imports, sometimes hundreds at once, and every one of them needs a proper SEO title and meta description. Writing those by hand at that volume just wasn't going to happen.
So I turned to Claude's structured output support. Instead of asking for JSON in the prompt and hoping it parses cleanly, you define the shape you want as a typed class and the API hands back a properly parsed object matching it, no string wrangling required:
class ProductSeoMetadata
{
#[Constrained(description: 'SEO title, 50-60 characters')]
public string $title;
#[Constrained(description: 'Meta description, 140-160 characters')]
public string $description;
}
$result = $client->messages->create(
model: 'claude-sonnet-5',
messages: [...],
outputConfig: ['format' => ProductSeoMetadata::class],
);
Two things caught me out while building this.
The first was thinking mode eating into the token budget meant for the actual answer. With extended
thinking on and a tight max_tokens, the model can burn through the whole budget reasoning and come
back with stop_reason: max_tokens and no text at all. If you're not watching for that specifically,
it just looks like the model returned nothing, and you'll waste a while assuming the bug is
somewhere else. Turning thinking off for this call fixed it straight away, a short SEO description
doesn't need much reasoning to begin with.
The second was that the length constraints in the schema are more of a hint than a rule. Writing
50-60 characters in the field description nudges things in the right direction most of the time,
but there's nothing stopping the model writing 80 characters if it wants to. I kept a plain
truncate() in place as a backstop rather than trusting the prompt to hold on its own.
Either way, nothing gets saved automatically. It shows up as a suggestion in the admin panel and a human decides whether to use it. Generating the copy in bulk saves a lot of time, publishing it without anyone looking is a different question entirely.