SpiderIQ Journal
We told every agent to send a parameter our own API rejected
SpiderIQ documents ?format=llm as the agent opt-in and ?format=json as the opt-out. 94 of the 114 endpoints that accept a format parameter refused one or both. Here is the census, the fix, and the negative control that makes the result a measurement.
SpiderIQ tells every agent that connects to it to send ?format=llm. The parameter turns on a guidance envelope: alongside the data, the response explains what the resource is for, what it is not for, and what to call next. We document ?format=json as the way to turn it back off.
For most of this year, on most of our endpoints, both of those values came back 422 Unprocessable Entity.
Following the documentation was the way to break the call
The failure had a shape worth describing precisely, because the obvious reading of it is wrong.

A middleware reads format off the raw query string and decides whether to splice in the guidance block. It never rewrites the query string. So an agent that sent no format parameter at all was never affected: it got the envelope, and it got a 200.
The 422 was reserved for callers who did what we told them to do. Send the value from our own documentation, and the request was refused at the door. That is a worse failure than a broken endpoint, because it punishes exactly the reader who paid attention.
Fifteen files each declared their own list
Underneath, there was no single definition of what format meant. Fifteen separate files each hand-wrote their own allowed list as a regular expression, most of them some variant of ^(yaml|md)$. Each one was written by someone solving the endpoint in front of them, and each one was individually reasonable.

Collectively they were a contract nobody owned. llm and json were absent from most of them, so most of the API rejected them. Nothing enforced consistency, which meant every new endpoint was free to invent a sixteenth vocabulary, and several had.
The census is the part that surprised us. Counting by hand, or by grep, gives the wrong answer in both directions: two files declare the pattern through a shared constant that a text search never sees, and FastAPI encodes an optional constrained parameter in a JSON shape that a naive reader scores as unconstrained, which is to say healthy. Taking the count from the generated API schema instead, with those two shapes resolved properly: 114 endpoints accept a format parameter, and 94 of them refused llm, json, or both.
One definition owns every format parameter
The fix is unglamorous. One module now owns every format vocabulary in the API. The ordinary case is a single four-value enum: json and llm return JSON, yaml returns text/yaml, md returns text/markdown.

Three endpoints genuinely differ, and they are declared rather than improvised. Two render Markdown but have no YAML renderer, so yaml is a deliberate 422 there. Two are exports whose natural default is CSV. Encoding those as named types, in the same module as the ordinary case, is what stops the next author from hand-rolling a sixteenth pattern.
A build check enforces it. Any route that declares format with a raw regular expression now fails the build. The rule is no longer a convention that a reviewer has to remember.
Widening what is accepted is not the same as ignoring what is sent. ?format=bogus is still a 422, carrying a structured error that names the parameter. An unsupported value is refused rather than quietly answered in JSON, which was never the bug.
The same script reported 94 on the old image and 0 on the new
A census that reports zero problems is worth nothing until you have watched it report a non-zero number. A checker that resolves nothing compares nothing to nothing and passes, and it looks identical to a clean bill of health.

So before trusting the result, we booted the previously deployed image and ran the byte-identical script against both:
endpoints refusing llm or json
previous image 114 94
current image 114 0Same denominator on both sides. That the script can and does report 94 is what makes the 0 a measurement rather than an assumption.
The same discipline was applied to the guard itself: before trusting it, one endpoint was deliberately reverted to the old pattern to confirm the build actually went red and named the offending routes.
What changed for you
If you send no format parameter, nothing about your calls has changed.
If you followed our documentation and sent ?format=llm or ?format=json, the call that used to return 422 now returns 200, with the content type the value asks for. yaml and md behave exactly as they did.
Build With SpiderIQ
Explore the API docs or keep reading the field notes from the SpiderIQ team.