thisago's blog


OpenAI with strict JSON Schema outputs

Table of Contents

There are many tutorials1 instructing you to use .description in your JSON Schema for structured outputs. But no one is telling this field is ignored. The official doc doesn't includes it in the "supported fields" but uses it all the time, implicitly telling it works.

Let's Take Conclusions

The test I'll be doing is simple:

  • Request a instruction at prompt and a divergent instruction at field description
  • I expect it to follow the property description.

I'll be using restclient.el because its syntax is a explicit and readable HTTP request. No magic behind.

Picking .choices.[0].message.content of the following request2, with strict schema:

:token := (+pass-get-secret "net/openai.com/token/blog")

:system = Start message with 'Hello'.
:schema-description = This MUST start with 'Hey'.
:user = Say hi

POST https://api.openai.com/v1/chat/completions
Content-Type: application/json
Authorization: Bearer :token

{
  "model": "gpt-4.1",
  "messages": [
    {"role": "system", "content": ":system"},
    {"role": "user", "content": ":user"}
  ],
  "response_format": {
  "type": "json_schema",
    "json_schema": {
      "name": "messageSchema",
      "strict": true,
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["message"],
        "properties": {
          "message": {
            "type": "string",
            "description": ":schema-description"
          }
        }
      }
    }
  },
  "temperature": 0.6
}
"{\"message\":\"Hey! How can I assist you today?\"}"

Conclusion

OK, I was wrong, it works. I will review my previous implementation that misled me into this conclusion.

I hope it can serve as example for how call the completions API it without SDKs.

Footnotes:

1

This was deleted for some reason, also the account. Wayback Machine only archived the profile BTW.

2

You can see the source of this page. Actually the selector is included in the source block header, which is not exported.