OpenAPI SDK readiness
Twilio - Api OpenAPI spec score
Octri scored the public spec at https://raw.githubusercontent.com/twilio/twilio-oai/main/spec/json/twilio_api_v2010.json for what a code generator can do with it. This is a reading of the document, not a grade of the API.
197 operations · 150 models · 75 tags · OpenAPI 3.0.1
Scored 14 September 2026 · fingerprint 170b3ccd0f89… · spec version 1.0.0 · server api.twilio.com
Document last changed 14 September 2026.
Where the points went
Every rule, heaviest first, with what it cost this document and how much of the surface it touched. Open a row for the locations.
Successful responses declare a schema2.00.4 lost1 of 197 operations
Without a response schema every method returns `unknown`/`any`, so callers get no types and no autocompletion.
GET /2010-04-01/Accounts/{AccountSid}/Recordings/{ReferenceSid}/AddOnResults/{AddOnResultSid}/Payloads/{PayloadSid}/Data.json`FetchRecordingAddOnResultPayloadData` declares no 2xx response at all.
Shared models live in components and are $ref'd2.00.5 lost12 of 197 operations
Inline object schemas become anonymous per-operation types. The same model inlined in 20 operations generates 20 near-identical types instead of one.
code, message, more_info, statusAn identical inline object (4 fields) appears in 2 operations. Move it to `components.schemas` and $ref it, or the SDK generates 2 separate types.ApiVersion, FriendlyName, MessageStatusCallback, PublicApplicationConnectEnabledAn identical inline object (16 fields) appears in 2 operations. Move it to `components.schemas` and $ref it, or the SDK generates 2 separate types.available_phone_numbers, end, first_page_uri, next_page_uriAn identical inline object (9 fields) appears in 7 operations. Move it to `components.schemas` and $ref it, or the SDK generates 7 separate types.end, first_page_uri, next_page_uri, notificationsAn identical inline object (9 fields) appears in 2 operations. Move it to `components.schemas` and $ref it, or the SDK generates 2 separate types.end, first_page_uri, next_page_uri, pageAn identical inline object (9 fields) appears in 3 operations. Move it to `components.schemas` and $ref it, or the SDK generates 3 separate types.- 7 more, not listed here.
Generated public names do not collide2.0Clean197 operations clean
When authored identifiers collapse to the same shared public name, the generator must silently rename one method; callers otherwise cannot predict the SDK surface from the spec.
Every path placeholder has a parameter1.5Clean197 operations clean
An undeclared `{id}` placeholder cannot become a typed method argument, so the generated request path is incomplete or uncompilable.
Every operation declares an operationId1.0Clean197 operations clean
Without one the generator synthesizes a name from the path, which changes whenever the path does. That is a silent breaking change for callers.
operationIds read as method names1.0Clean197 operations clean
The id becomes the method name. `ActionsActionsGet` generates `client.actions.actionsActionsGet()`; `getActions` generates `client.actions.get()`.
Operations carry a summary or description1.00.4 lost47 of 197 operations
Operation prose becomes the method's doc comment, the text an IDE shows on hover.
POST /2010-04-01/Accounts/{AccountSid}/Addresses.json`CreateAddress` has neither summary nor description, so its generated method ships without documentation.GET /2010-04-01/Accounts/{AccountSid}/Addresses.json`ListAddress` has neither summary nor description, so its generated method ships without documentation.DELETE /2010-04-01/Accounts/{AccountSid}/Addresses/{Sid}.json`DeleteAddress` has neither summary nor description, so its generated method ships without documentation.GET /2010-04-01/Accounts/{AccountSid}/Addresses/{Sid}.json`FetchAddress` has neither summary nor description, so its generated method ships without documentation.POST /2010-04-01/Accounts/{AccountSid}/Addresses/{Sid}.json`UpdateAddress` has neither summary nor description, so its generated method ships without documentation.- 42 more, not listed here.
Request bodies are documented1.00.2 lost5 of 197 operations
Body field descriptions become the doc comments on generated parameters; without them the SDK ships undocumented arguments.
POST /2010-04-01/Accounts/{AccountSid}/Messages/{MessageSid}/Feedback.json`CreateMessageFeedback` has an undocumented request body, so every generated parameter for it will be comment-free.POST /2010-04-01/Accounts/{AccountSid}/Calls/{CallSid}/Transcriptions/{Sid}.json`UpdateRealtimeTranscription` has an undocumented request body, so every generated parameter for it will be comment-free.POST /2010-04-01/Accounts/{AccountSid}/SigningKeys/{Sid}.json`UpdateSigningKey` has an undocumented request body, so every generated parameter for it will be comment-free.POST /2010-04-01/Accounts/{AccountSid}/Calls/{CallSid}/Siprec/{Sid}.json`UpdateSiprec` has an undocumented request body, so every generated parameter for it will be comment-free.POST /2010-04-01/Accounts/{AccountSid}/Calls/{CallSid}/Streams/{Sid}.json`UpdateStream` has an undocumented request body, so every generated parameter for it will be comment-free.
Failure responses are declared1.01.0 lost195 of 197 operations
Declared error schemas become typed errors. Without them every failure surfaces as an untyped generic error.
POST /2010-04-01/Accounts.json`CreateAccount` declares no 4xx/5xx or default response, so SDK users get no typed error for it.GET /2010-04-01/Accounts.json`ListAccount` declares no 4xx/5xx or default response, so SDK users get no typed error for it.GET /2010-04-01/Accounts/{Sid}.json`FetchAccount` declares no 4xx/5xx or default response, so SDK users get no typed error for it.POST /2010-04-01/Accounts/{AccountSid}/Addresses.json`CreateAddress` declares no 4xx/5xx or default response, so SDK users get no typed error for it.GET /2010-04-01/Accounts/{AccountSid}/Addresses.json`ListAddress` declares no 4xx/5xx or default response, so SDK users get no typed error for it.- 190 more, not listed here.
Operations are tagged1.0Clean197 operations clean
Tags drive namespacing. Untagged operations fall back to a path segment, producing lopsided or `misc` namespaces.
No duplicate or equivalent paths1.0Clean121 paths clean
Paths differing only in parameter NAME are the same route to a server; the generated SDK ends up with two methods that call the same endpoint.
Authentication is described1.0CleanDeclared
Security schemes generate the SDK's auth configuration. A spec without them produces a client with no way to authenticate.
Parameters explain their purpose0.750.17 lost7 of 197 operations
Parameter descriptions become IDE hints on generated method arguments; bare names force SDK users back to the API reference.
GET /2010-04-01/Accounts/{AccountSid}/SigningKeys.json#path:AccountSid`AccountSid` has no description, so the generated argument has no IDE guidance.GET /2010-04-01/Accounts/{AccountSid}/SigningKeys/{Sid}.json#path:AccountSid`AccountSid` has no description, so the generated argument has no IDE guidance.GET /2010-04-01/Accounts/{AccountSid}/SigningKeys/{Sid}.json#path:Sid`Sid` has no description, so the generated argument has no IDE guidance.POST /2010-04-01/Accounts/{AccountSid}/SigningKeys/{Sid}.json#path:AccountSid`AccountSid` has no description, so the generated argument has no IDE guidance.POST /2010-04-01/Accounts/{AccountSid}/SigningKeys/{Sid}.json#path:Sid`Sid` has no description, so the generated argument has no IDE guidance.- 2 more, not listed here.
A server URL is declared0.5CleanDeclared
Without a server URL the generated client must ship with an empty or placeholder base URL, adding setup work and easy production misconfiguration.
What 7.3 means for an SDK
A mixed reading, and the three rules that decide most of it.
The client compiles and works. Callers will feel the soft spots: a few methods that return an untyped value, arguments with no hint on them, a namespace or two named after a path segment rather than a resource.
Three rules carry six of the 10 points between them. On this document they took 0.91.
−0.4
Successful responses declare a schema
1 of 197 operations
−0.5
Shared models live in components and are $ref'd
12 of 197 operations
Clean
Generated public names do not collide
197 operations clean
What to change first
Every rule that deducted, in the order they cost.
Successful responses declare a schema
Give the success response a schema, or a $ref to one in components. A 204 needs nothing. Inside Octri this one has a one-click fix.
Shared models live in components and are $ref'd
Move the shape into components.schemas once and $ref it from each operation that returns or accepts it.
Operations carry a summary or description
Write one sentence of summary. It lands on the reference page and in the SDK's doc comment. Inside Octri this one has a one-click fix.
Request bodies are documented
Describe the body, or the fields inside it. Field-level prose is the one that reaches the SDK's arguments. Inside Octri this one has a one-click fix.
Failure responses are declared
Declare the failures you actually return, or one `default` response carrying your error shape.
Parameters explain their purpose
Describe what the parameter does and what a valid value looks like. One line each. Inside Octri this one has a one-click fix.
The spec at raw.githubusercontent.comis public. Octri keeps the `info` block, the score, and up to five sample finding locations per rule. The document itself is not stored and is not served from here. The audit predicts what an SDK generator can do with the description; it is not a security review, an uptime measurement or a critique of the API’s design. This page is not affiliated with Twilio - Api or Twilio Support.