Format output_schema keywords: pattern and minLength yes, not no

Which JSON Schema keywords a Sume Format output_schema accepts (pattern, minLength, multipleOf, enum, const) and which fail as unsupported_keyword.

5 min readSume
All posts

A Sume Format output_schema accepts a fixed allowlist: type, properties, required, additionalProperties, items, $defs, $ref, anyOf, enum, const, string and number bounds, minItems and maxItems, plus annotations. Anything off the list, including not, if / then / else, patternProperties and allOf, fails at create with 400 output_schema_invalid and the rule unsupported_keyword.

The list is from the Structured output page, which states that a keyword outside it is a violation and not something silently dropped.

Which keywords are accepted?

Grouped as the docs group them:

Accepted keywords in a Format output_schema, from Sume's Structured output page (read 2026-10-03)
GroupAccepted
Structuretype, properties, required, additionalProperties, items, $defs, $ref, anyOf
Valuesenum, const
Stringsformat, pattern, minLength, maxLength
Numbersminimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf
ArraysminItems, maxItems
Annotationtitle, description, default, examples, $schema, $id

Are the accepted constraints really enforced?

Yes, and that is the useful part. The docs say Ajv enforces exactly the keywords you wrote and the platform adds no floor of its own. A pattern on an SKU field or a maximum on a price is checked against what the run produced, and a miss ends in output_schema_unsatisfied rather than a quiet pass.

The flip side is that over-tight constraints turn a good run into output: null. minItems: 1 on a scene list rejects the very ledger you wanted to read after a partial failure, so the docs advise leaving it off arrays you want to receive partially.

Which keywords are rejected, and what replaces them?

These are the ones that catch real integrations, with the docs' suggested substitute.

Rejected keywords and the documented substitute (read 2026-10-03)
RejectedInstead
oneOfanyOf
allOfFlatten the branches into one object
not, if / then / else, dependentRequired, dependentSchemasModel alternatives as anyOf, or validate after reading output
nullable: true"type": ["string", "null"]
patternProperties, propertyNames, unevaluatedProperties, additionalItemsDeclare the properties; additionalProperties: false covers the rest

How do I find every bad keyword in one request?

Send the schema and read the 400. Every problem is reported, not just the first, as { path, rule, message } in details.violations[]. Branch on rule, which is stable; message is for people and may change.

A rejected create costs nothing and does not consume your Idempotency-Key, which is released on failure. Fix all the listed paths, then resend with the same key. The Errors and spend page lists the create-time codes alongside this one.

What should I validate on my side instead?

Cross-field rules are the gap. Without if / then / else or dependentRequired, you cannot say "if kind is video, then url must be a video" in the schema. The docs' answer is to model alternatives as anyOf, or validate after reading output.

A practical split: put shape and per-field bounds in the schema, where a miss fails the run visibly, and put business rules in your own code after you have read a completed receipt with output_error null.

Four limits apply to the document you send: nesting depth of 10 levels, 5000 properties in total, 1000 values per enum, and 120,000 characters summed over every property name, key and string value. They report as max_depth, max_properties, max_enum_values and max_string_length.

The last is a document-wide budget, so long description annotations on a large schema can exhaust it even when no single string looks large. Descriptions are accepted annotations, but trim them if you approach the limit.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume