When an LLM calls an API, it generates structured data. When an API receives a request, it expects bytes in a specific format. These are different worlds.
Call them semantic space and protocol space. LLMs operate in semantic space—structured objects, typed fields, nested data. APIs operate in protocol space—URL-encoded query strings, multipart boundaries, RFC-compliant headers. The gap between them is where things get interesting.
The translation problem
We need to lift low-level schemas into semantic space so LLMs can work with them. And we need to project semantic data back into protocol space so APIs accept them. The transformations must be rigorous—no silent failures, no malformed requests.
Protocol space is fixed. APIs require what they require. If an endpoint expects multipart/form-data with a specific boundary format, that’s non-negotiable.
Semantic space is flexible. We choose how to present interfaces to LLMs. This is where the synthesis happens—finding representations that LLMs can reliably generate and that we can rigorously transform.
The attention problem
The obvious question: can an LLM generate valid API parameters? With enough focus, probably. But that’s the wrong question.
When you ask an LLM to configure a SaaS deployment, API calls are incidental. The LLM is thinking about your deployment requirements, not HTTP encoding rules. Uploading a configuration file is one step among dozens. The LLM’s attention is on the task, not the mechanics.
This changes the problem. It’s not “can an LLM generate multipart data” but “can an LLM generate multipart data reliably while thinking about something else.” The answer is: not without help.
Interface synthesis isn’t just presenting schemas to LLMs. It’s transforming them into forms that remain robust when attention is divided.
The encoding maze
OpenAPI’s encoding model is where complexity explodes.
Start with parameter styles: simple, form, label, matrix, spaceDelimited, pipeDelimited, deepObject. Each serializes data differently. Add explode modes that interact with styles in non-obvious ways. Add the fact that defaults vary by parameter location—query parameters default to form style with explode, path parameters default to simple without.
Now add content encodings. Parameters can have schemas directly, or they can have content with media types. When they have content, each media type can have its own schema. Property-specific encoding rules can override content types, add headers, specify styles. These rules interact with the schema’s own encoding keywords—contentEncoding, contentMediaType, contentSchema—in ways the spec doesn’t fully define.
Special cases multiply. application/x-www-form-urlencoded has its own serialization rules. Multipart encodings have part generation rules, boundary handling, nested content types. The presence or absence of a schema changes which rules apply.
These mechanisms permute. Style × explode × location × content-type × property encoding × schema encoding keywords. The naive implementation is a combinatorial nightmare.
The synthesis insight
We needed an approach that wouldn’t blow up in our face. The key was recognizing that content encoders could serve dual purposes: they generate schemas for LLMs and they encode values for APIs.
Consider multipart form data. The protocol schema says: object with properties, each property becomes a part. But that’s not LLM-friendly. What if a part needs a specific filename? What about the content type? Custom headers?
So we synthesize a different interface. Each part can be a simple value (just the content) or an object with domain properties: $content for the payload, $filename for the filename, $contentType to override the media type, $headers for additional headers. The LLM generates what it can naturally express. The encoder handles the transformation.
This is a mini-DSL embedded in the schema. The LLM doesn’t need to understand multipart boundaries or Content-Disposition headers. It expresses intent through structured properties. We handle the rest.
Composition through delegation
The same encoder that generates the transformed schema also knows how to encode values. This threading is essential.
Multipart parts can contain any content type. A part might be JSON, or plain text, or binary, or even another composite encoding. The multipart encoder doesn’t hardcode these cases. It delegates to other encoders based on content type.
When synthesizing the schema, the multipart encoder asks each part’s encoder for its schema. When encoding values, it asks each encoder to encode its part. The encoders compose. Nested multipart just works because the multipart encoder delegates to… itself, for nested parts.
This composability depends on the dual-purpose design. If schema generation and encoding were separate systems, composition would require parallel hierarchies that could drift out of sync. With unified encoders, composition is natural.
Finding the semantic sweet spot
Protocol space is fixed. Semantic space is vast. Interface synthesis is finding the point in semantic space that satisfies two constraints:
- LLMs can reliably generate instances, even with divided attention
- We can rigorously transform those instances into valid protocol data
Too close to protocol space and LLMs struggle—they’d need to understand encoding rules while thinking about user tasks. Too abstract and the transformation becomes lossy or ambiguous.
The multipart DSL is one example of this balance. It’s concrete enough that transformation is deterministic. It’s abstract enough that LLMs can generate it naturally. The domain properties ($filename, $contentType) capture the semantically meaningful choices while hiding the mechanical ones.
This is what interface synthesis means. Not just presenting API schemas to LLMs, but deliberately designing the semantic interface to optimize for both generation reliability and transformation rigor.
What comes next
We’ve described the problem and the approach. Content encoders that unify schema generation and value encoding. Composition through delegation. Semantic interfaces designed for LLM reliability.
But we haven’t shown how this actually executes—how parameter styles collapse into a uniform model, how the encoding system avoids combinatorial explosion, how content negotiation works at both ends.
That’s the execution story, and it’s where the engineering gets concrete. Continue to Part 2: Spec-Driven Execution.
