docs: add operation descriptions and typed error bodies to the OpenAPI spec - #426
Open
shirgoldbird wants to merge 2 commits into
Open
docs: add operation descriptions and typed error bodies to the OpenAPI spec#426shirgoldbird wants to merge 2 commits into
shirgoldbird wants to merge 2 commits into
Conversation
…I spec
Three changes, all to make the spec self-describing for API clients and
agents that read it instead of the prose docs.
1. Add `description` to the 27 operations that only had a `summary`.
2. Give every error response a JSON schema. 141 error responses declared
only a description and no `content`, so a client reading the spec could
not tell that DeepL returns a parseable JSON body at all. Fixed at the
source by filling in 6 shared `components/responses` plus two inline
415s that now `$ref` the existing shared response.
3. Add `InfrastructureErrorResponse` and use `oneOf` on 414/500/503/504.
Probing the live API showed the edge layer returns a different body
shape than the application does: `{"error":{"message":"Bad Gateway."}}`
versus `{"message":"..."}`. Declaring only the application shape on
those codes would have been wrong.
openapi.json regenerated from the YAML with yq, and verified structurally
identical to it.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
shirgoldbird
force-pushed
the
docs/openapi-error-schemas-and-descriptions
branch
from
September 9, 2026 14:33
6693029 to
8738571
Compare
Contributor
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
The spec as served could not be parsed by strict OpenAPI 3.0 tooling, so
anything generating clients or tool definitions from it got nothing,
regardless of how complete the descriptions were.
Three causes, all pre-existing:
- 512 response-code keys were unquoted, so YAML parses them as integers.
OpenAPI requires Responses Object keys to be strings; validators don't
just warn, they fail ("expected string or bytes-like object, got 'int'").
The generated JSON was unaffected, but that file is in .mintignore and
isn't published, so the only fetchable spec was the one that wouldn't
parse.
- OutlineDetectionOptionStr declared enum: ['0'] with default: '1', a
default outside its own enum. Its siblings PreserveFormattingOptionStr
and SplitSentencesOption both list '0' and '1', and the boolean
OutlineDetectionOption defaults to true, so the enum was simply missing
'1'.
- VoiceSourceLanguage had an empty default:, which parses as null against
a string enum. Removed rather than given a value; an absent default is
how "no default" is expressed.
Verified against the deployed preview: openapi-spec-validator reports 0
errors on the spec as served, all 512 response keys parse as strings, the
auth_header security scheme is now visible to parsers, and 62/62
operations expose an operationId and a description. The YAML and JSON also
now parse to identical structures without key normalization.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
shirgoldbird
force-pushed
the
docs/openapi-error-schemas-and-descriptions
branch
from
September 9, 2026 14:49
ac888f8 to
5b5bb0a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Spec-only changes, from an audit of how machine-readable our API surface is. No behavior claims beyond what the live API already does, but points 2 and 3 assert things about the API's error contract, so they want a review from someone who owns that contract.
Precedent: #366 ("fix(openapi): add response body to generic error responses", merged 2026-06-08) did exactly this for 7 shared error responses —
BadRequest,Unauthorized,Forbidden,NotFound,PayloadTooLarge,TooManyRequests,QuotaExceeded— for the same reason. Point 2 below covers the 6 that PR left behind, so most of this change is following that precedent rather than setting new policy. Point 3 is the one genuinely new judgment call.1.
descriptionon 27 operations27 of 62 operations had only a
summary. Anything that generates a client or a tool definition from the spec had nothing to work from for those endpoints.2. A JSON schema on every error response
141 error responses declared only a
descriptionand nocontent. Reading the spec, a client could not tell that DeepL returns a parseable JSON body on an error at all.Fixed at the source rather than per-operation, continuing #366: 6 shared
components/responses(InternalServerError,ServiceUnavailable,ForbiddenGlossaries,URITooLong,UnsupportedMediaTypeGlossaries,QuotaExceededGlossaries) now declareapplication/json, and two inline415s now$refthe sharedUnsupportedMediaTyperesponse instead of duplicating it.3.
InfrastructureErrorResponse, withoneOfon 414/500/503/504While probing the live API I found the edge layer returns a different error shape than the application:
versus the application's
{"message": "..."}. So declaring onlyErrorResponseon the codes that either layer can produce would have been wrong. Those four now useoneOf: [ErrorResponse, InfrastructureErrorResponse].This is the part #366 did not have to decide, since the codes it touched are all application-level.
Questions for the reviewer
oneOfsplit on 414/500/503/504 right? I mapped the two shapes by observation. Someone who knows which layer serves which status code should confirm, especially for 503/504.responses, but the edge clearly returns it. Adding it across 62 operations is a call on what the edge guarantees, so I left it out.POST /v2/glossaries(v2) got "For new integrations we recommendPOST /v3/glossaries" rather than any deprecation wording, perCLAUDE.md. Flagging in case a stronger signal is wanted.Verification
openapi.jsonregenerated withyq -o=json, verified structurally identical to the YAML.mint broken-links --check-anchors: same finding count before and after, all pre-existing (pipeline/drafts/and existing anchor drift).mint dev: all API reference pages still render, new descriptions confirmed on the rendered pages.mainon 2026-09-09 to pick up the six interveningopenapi.yamlchanges (Voice French variants, hr/tl translated speech, glossary term-matching limits). Clean rebase, no conflicts; the only removed lines in the diff are the two inline 415 descriptions replaced by the$ref.Note
openapi.yamlalso lives in theopenapirepo. These changes still need porting there. (sync-openapi-specs.ymlruns on push tomainand may handle this automatically — worth confirming on merge.)🤖 Generated with Claude Code