OpenAI text.format json_schema to a Sume Format response_format
Move an OpenAI Responses API text.format schema onto a Sume Format run: nest it under response_format.json_schema, or lift it into output_schema.

If your code builds an OpenAI Responses API body with text.format, Sume will not accept that shape on a Format run. Either lift name, strict and schema into Sume's output_schema, or re-nest them as response_format: { type: "json_schema", json_schema: { ... } }.
OpenAI's page, Structured model outputs, read on 2026-10-02, shows the Responses form as text: { format: { type: "json_schema", "strict": true, "schema": ... } }. Sume's side is from Structured output.
What exactly differs between the two spellings?
Sume's alias mirrors the Chat Completions style: type at the top, the binding nested under json_schema. The Responses API flattens the same fields into text.format. That flattened shape is not accepted on a Format run.
| Spelling | Where the fields sit | Accepted by Sume |
|---|---|---|
| output_schema | name, strict, schema at the top of the object | Yes, native |
| response_format | type plus json_schema holding name, strict, schema | Yes, normalized to output_schema |
| text.format (Responses) | type, name, strict, schema flattened | No |
How do I convert a Responses body?
Take the object under text.format, drop its type, and place the rest under output_schema. This is the shortest path and the one the receipt echoes back, because response_format is normalized into output_schema on the receipt anyway.
{
"instruction": "Make one hero image for the linked product.",
"output_schema": {
"name": "acme/promo-hero/v1",
"strict": true,
"schema": {
"type": "object",
"additionalProperties": false,
"required": ["headline"],
"properties": { "headline": { "type": "string" } }
}
}
}Can I send both?
No. Sending output_schema and response_format together is 400 invalid_request. Pick one per request. Nothing runs and nothing is charged on a 400 at submit.
What else behaves differently from OpenAI?
The subset rules come from the same strict-mode guidance, but where they apply is different. With OpenAI you constrain what the model says. On a Sume Format run the schema constrains how a finished run is read back, so it cannot make a Format produce a video it does not make.
There is also no equivalent of OpenAI's JSON mode (json_object), and strict: false is accepted but changes nothing: a schema outside the subset is rejected either way with 400 output_schema_invalid and a details.violations[] list. Streamed partial JSON does not exist here, because output appears once on the terminal receipt.
What can still go wrong after a clean 202?
The run can finish and still return output: null with an output_error such as output_schema_unsatisfied, for example when a required media field names a file the Format never made. On an API run that is a failure, not a draft. Check output_error before reading output, and fall back to artifacts[] to show the media anyway.
A quick migration checklist
Every problem is reported in one 400 with a stable lowercase rule token such as required_completeness or unsupported_keyword, so you can fix the whole schema in one pass.
- Rename the container:
text.formatbecomesoutput_schema, withtypedropped. - Keep
name(1 to 64 characters of letters, digits,.,_,/,-) and namespace it, since it lands on every receipt. - Replace
oneOfwithanyOf, flattenallOf, and writenullable: trueas a type union withnull. - Add
additionalProperties: falseto every object and list every property inrequired. - Use only
#/$defs/*andSumeMediaFile#for$ref; root recursion with$ref: "#"is rejected.
Why not accept text.format directly?
Sume documents one native spelling and one alias. The alias mirrors Chat Completions, so a client that builds Chat bodies works unchanged, and the receipt normalizes it to output_schema. A Responses-style body needs a small change, and the docs say to lift the fields or re-nest them, not to send text.format.
Unknown top-level fields are rejected with 400 unknown_parameter, with a suggestion when the name is close, so a stray text key surfaces at submit rather than being ignored.
What happens to refusals and truncation?
OpenAI's refusal has no equivalent. The Sume counterpart is output_error on the receipt, which is a failed projection and not a safety refusal. There is no truncated-JSON case either: the projection is small and bounded, and output appears once on the terminal receipt.
If you used partial-JSON streaming to render progress, switch to the phase timeline at events_url or take the terminal webhook. There is no push channel for progress.
Sources
Related posts
More in Formats
- Sume agent_reported_failure: the three reasons and what to do
agent_reported_failure on a Sume run means the run's own receipt said it did not deliver. Its details.reason tells you which of three cases it was.
- Sume primary_output_missing: schema satisfied, run still failed
A Sume run can match your output_schema and still end failed with primary_output_missing. It means the key named in primary_output_key had no value.
- Sume output_extraction_failed: the run stays completed, reread it
output_extraction_failed with reason harvest_unavailable is transient. The Sume run stays completed and fills in on your next read; retry only if it persists.
- Pick a Format from the list: io profile and showcase before you run
GET /v1/formats returns each Format with an io profile (input_kind and output_kind) and a showcase output, so you can choose one without paying for a trial run.
Written by Sume