JSON Schema compatibility checker
Paste a JSON Schema and see, per provider, what is refused, what is undocumented and what changes on the way — with a version fixed for Anthropic.
What it does
Paste a JSON Schema. It can be on its own, inside a response format (OpenAI's response_format, Anthropic's output_config.format, the Responses API's text.format), or inside a tool definition in any provider's shape. The checker finds the schema and where it is used. Then, for every provider, it shows two things:
- What the provider's own documentation says it refuses, and which keywords it does not mention.
- What Salyro measured happens to the schema on the way through its gateway.
Each finding names its path in the schema and its line, and says where the rule comes from. Each card sums it up:
- Refused — a rule the page states is broken, and the page says the request is refused.
- Accepted, not enforced — the page says the schema guides the model but is not enforced.
- Changed on the way — through Salyro, part of the schema is removed before it reaches the provider.
- Needs review — something the page leaves open: a keyword it does not mention, or a rule it states without saying what breaking it does.
- Accepted — nothing the page states is broken, and nothing is left open.
- Unknown — the provider's page could not be read.
A trailing comma or a comment in what you paste is read, and shown as a warning: a provider's API refuses both as invalid JSON. Everything runs in your browser: nothing you paste is sent anywhere.
Where the rules come from
A rule is shown only when a source states it. A keyword no source mentions is unknown. It is never "enforced" or "refused" from memory.
- Anthropic. The rules come from Anthropic's page on structured outputs, which JSON outputs and strict tool use share.
- Refused with a 400: numerical constraints, string length constraints, array constraints beyond
minItemsof 0 or 1,additionalPropertiesset to anything butfalse, recursive schemas, external$ref, and objects in anenum. - Listed as not supported, without saying they are refused:
allOfwith$ref, and in apattern, backreferences, lookarounds, word boundaries and large{n,m}ranges. The page says complex patterns "may result in 400 errors". These are shown as needing review, not as refused. - Limits: 24 optional properties and 16 union types across the strict schemas of a request.
- A caveat: the capitalization of string
enumandconstvalues is not guaranteed, so the answer should be compared case-insensitively. - Not enforced: a tool without
strict: true.
- Refused with a 400: numerical constraints, string length constraints, array constraints beyond
- OpenAI, Google Gemini and xAI. Their documentation could not be read when these rules were compiled. So everything about the schemas they accept is shown as unknown, until someone reads the pages and records them.
- Through Salyro. These rows are the gateway's own measurements, made with the pinned proxy against a server that recorded the request each provider would receive.
- Response schemas: OpenAI receives the schema with
strict: true. Anthropic and Google receive it translated into their own structured-output field. xAI receives it unchanged, and nothing states that xAI honours it. - Strict tools:
strict: trueon a tool reaches only OpenAI, so Salyro refuses it for the others rather than drop it silently. - Gemini tools:
additionalPropertiesis removed from a tool's parameters on the way to Gemini.
- Response schemas: OpenAI receives the schema with
Make compatible for Anthropic
When a finding can be fixed without deciding something for you, Make compatible for Anthropic rewrites the schema the way Anthropic's SDKs do:
- It removes the unsupported constraints and writes each one into the description ("Must be at least 1").
- It sets
additionalProperties: falseon every object. - It moves string formats Anthropic does not list into the description.
The result keeps the wrapper you pasted, and comes with a diff. Every change that alters what the schema means is marked. A constraint in a description is a hint the model reads, no longer a rule the answer is held to; additionalProperties: false means the object can no longer carry keys you did not list.
What cannot be rewritten safely stays a finding: a recursive schema, an external reference, an object in an enum, an unsupported pattern, or a schema over the limits. Nothing under not or if is rewritten, because there a schema is a condition, and removing a constraint would change what it accepts. Make compatible is not offered when a number in the schema is too large or too precise for the browser to read exactly, because the rewrite would write it back changed.
What it does not know
- Which keywords OpenAI, Gemini and xAI accept, refuse or ignore. Their pages could not be read, and no per-keyword test against a real model has been run yet. When one is, its results will reach this tool the same way the gateway's measurements do.
- Keywords Anthropic's page neither supports nor forbids by name, such as
title,oneOfornot. They are listed as unknown. - Whether a given model follows the schema well. The checker reads the schema; it does not call a model.
FAQ
Why does Anthropic refuse minimum in my schema?
Anthropic's structured outputs compile the schema into a grammar, and its page lists numerical constraints such as minimum, maximum and multipleOf as not supported. A request that uses one is refused with a 400. Make compatible moves the constraint into the description, where the model reads it as guidance. Check the answer in your own code if the bound matters.
Why is every OpenAI keyword "unknown"?
Every rule here needs the provider's own page behind it, and OpenAI's could not be read when these rules were compiled. An unknown is shown as unknown rather than guessed.
Does Gemini keep additionalProperties?
Through Salyro, not in a tool's parameters. The gateway's measurements show it removed on the way to Gemini, silently. What Gemini itself does with the keyword when called directly is not recorded here.
Sources
The Anthropic rules quote Anthropic's structured outputs page (its "JSON Schema limitations" section) and its strict tool use page, as read on 25 September 2026. The gateway's rows are generated from its routing code, so a change there that is not regenerated fails the build. Every rule's source, date and quote is recorded as Reference Data and listed in the public tools' data freshness report.
Where the numbers come from
- Model and pricing data is a snapshot of the catalogue Salyro itself uses, taken when this site was built.
- Facts about models and providers that are not in that catalogue carry their own source and the date they were checked, and are shown as unknown where no reliable source exists.
