OpenAPI SDK readiness

GitHub v3 REST API OpenAPI spec score

Octri scored the public spec at https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json for what a code generator can do with it. This is a reading of the document, not a grade of the API.

6.8/ 10
Mixed

1229 operations · 975 models · 47 tags · OpenAPI 3.0.3

Scored 14 September 2026 · fingerprint 4340ac8202fa… · spec version 1.1.4 · server api.github.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.

  1. Successful responses declare a schema2.00.4 lost21 of 1229 operations

    Without a response schema every method returns `unknown`/`any`, so callers get no types and no autocompletion.

    • GET /assignments/{assignment_id} `classroom/get-an-assignment` declares no 2xx response at all.
    • GET /assignments/{assignment_id}/accepted_assignments `classroom/list-accepted-assignments-for-an-assignment` declares no 2xx response at all.
    • GET /assignments/{assignment_id}/grades `classroom/get-assignment-grades` declares no 2xx response at all.
    • GET /classrooms `classroom/list-classrooms` declares no 2xx response at all.
    • GET /classrooms/{classroom_id} `classroom/get-a-classroom` declares no 2xx response at all.
    • 16 more, not listed here.

    What this rule checks

  2. Shared models live in components and are $ref'd2.00.4 lost25 of 1229 operations

    Inline object schemas become anonymous per-operation types. The same model inlined in 20 operations generates 20 near-identical types instead of one.

    • tasks, total_active_count, total_archived_count An identical inline object (3 fields) appears in 2 operations. Move it to `components.schemas` and $ref it, or the SDK generates 2 separate types.
    • documentation_url, errors, message An identical inline object (3 fields) appears in 25 operations. Move it to `components.schemas` and $ref it, or the SDK generates 25 separate types.
    • content_type, insecure_ssl, secret, url An identical inline object (4 fields) appears in 3 operations. Move it to `components.schemas` and $ref it, or the SDK generates 3 separate types.
    • advanced_security, code_scanning_default_setup, code_scanning_default_setup_options, code_scanning_delegated_alert_dismissal An identical inline object (23 fields) appears in 2 operations. Move it to `components.schemas` and $ref it, or the SDK generates 2 separate types.
    • description, group_id, name, notification_setting An identical inline object (6 fields) appears in 2 operations. Move it to `components.schemas` and $ref it, or the SDK generates 2 separate types.
    • 20 more, not listed here.

    What this rule checks

  3. Generated public names do not collide2.0Clean1229 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.

    What this rule checks

  4. Every path placeholder has a parameter1.5Clean1229 operations clean

    An undeclared `{id}` placeholder cannot become a typed method argument, so the generated request path is incomplete or uncompilable.

    What this rule checks

  5. Every operation declares an operationId1.0Clean1229 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.

    What this rule checks

  6. operationIds read as method names1.00.3 lost165 of 1229 operations

    The id becomes the method name. `ActionsActionsGet` generates `client.actions.actionsActionsGet()`; `getActions` generates `client.actions.get()`.

    • GET / `meta/root` reads better as `getRoot` at the call site.
    • POST /app/hook/deliveries/{delivery_id}/attempts `apps/redeliver-webhook-delivery` reads better as `createRedeliverWebhookDelivery` at the call site.
    • PUT /app/installations/{installation_id}/suspended `apps/suspend-installation` reads better as `updateSuspendInstallation` at the call site.
    • DELETE /app/installations/{installation_id}/suspended `apps/unsuspend-installation` reads better as `deleteUnsuspendInstallation` at the call site.
    • PATCH /applications/{client_id}/token `apps/reset-token` reads better as `updateResetToken` at the call site.
    • 160 more, not listed here.

    What this rule checks

  7. Operations carry a summary or description1.0Clean1229 operations clean

    Operation prose becomes the method's doc comment, the text an IDE shows on hover.

    What this rule checks

  8. Request bodies are documented1.00.2 lost30 of 1229 operations

    Body field descriptions become the doc comments on generated parameters; without them the SDK ships undocumented arguments.

    • PATCH /app/hook/config `apps/update-webhook-config-for-app` has an undocumented request body, so every generated parameter for it will be comment-free.
    • POST /markdown/raw `markdown/render-raw` has an undocumented request body, so every generated parameter for it will be comment-free.
    • PUT /orgs/{org}/actions/permissions `actions/set-github-actions-permissions-organization` has an undocumented request body, so every generated parameter for it will be comment-free.
    • PUT /orgs/{org}/actions/permissions/workflow `actions/set-github-actions-default-workflow-permissions-organization` has an undocumented request body, so every generated parameter for it will be comment-free.
    • POST /orgs/{org}/attestations/delete-request `orgs/delete-attestations-bulk` has an undocumented request body, so every generated parameter for it will be comment-free.
    • 25 more, not listed here.

    What this rule checks

  9. Failure responses are declared1.00.5 lost381 of 1229 operations

    Declared error schemas become typed errors. Without them every failure surfaces as an untyped generic error.

    • GET / `meta/root` declares no 4xx/5xx or default response, so SDK users get no typed error for it.
    • GET /app `apps/get-authenticated` declares no 4xx/5xx or default response, so SDK users get no typed error for it.
    • GET /app/hook/config `apps/get-webhook-config-for-app` declares no 4xx/5xx or default response, so SDK users get no typed error for it.
    • PATCH /app/hook/config `apps/update-webhook-config-for-app` declares no 4xx/5xx or default response, so SDK users get no typed error for it.
    • GET /app/installations `apps/list-installations` declares no 4xx/5xx or default response, so SDK users get no typed error for it.
    • 376 more, not listed here.

    What this rule checks

  10. Operations are tagged1.0Clean1229 operations clean

    Tags drive namespacing. Untagged operations fall back to a path segment, producing lopsided or `misc` namespaces.

    What this rule checks

  11. No duplicate or equivalent paths1.00.2 lost2 of 815 paths

    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.

    • /orgs/{}/attestations/{} 2 paths are the same route with different parameter names: /orgs/{org}/attestations/{attestation_id}, /orgs/{org}/attestations/{subject_digest}.
    • /users/{}/attestations/{} 2 paths are the same route with different parameter names: /users/{username}/attestations/{attestation_id}, /users/{username}/attestations/{subject_digest}.

    What this rule checks

  12. Authentication is described1.01.0 lostNot declared

    Security schemes generate the SDK's auth configuration. A spec without them produces a client with no way to authenticate.

    • components.securitySchemes No security schemes are declared, so the generated client exposes no authentication configuration.

    What this rule checks

  13. Parameters explain their purpose0.750.18 lost54 of 1229 operations

    Parameter descriptions become IDE hints on generated method arguments; bare names force SDK users back to the API reference.

    • POST /app-manifests/{code}/conversions#path:code `code` has no description, so the generated argument has no IDE guidance.
    • GET /app/hook/deliveries/{delivery_id}#path:delivery_id `delivery_id` has no description, so the generated argument has no IDE guidance.
    • POST /app/hook/deliveries/{delivery_id}/attempts#path:delivery_id `delivery_id` has no description, so the generated argument has no IDE guidance.
    • GET /app/installations#query:outdated `outdated` has no description, so the generated argument has no IDE guidance.
    • GET /apps/{app_slug}#path:app_slug `app_slug` has no description, so the generated argument has no IDE guidance.
    • 49 more, not listed here.

    What this rule checks

  14. 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 this rule checks

Packaging, outside the score

This generates one package with 1229 operations and 975 models. Frontend consumers download all of it to call any of it, and low-spec machines pay for it in IDE and build time. The largest groups are `repos` (203), `actions` (189), `orgs` (110), and each is a candidate for its own project.

What 6.8 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.86.

−0.4

Successful responses declare a schema

21 of 1229 operations

−0.4

Shared models live in components and are $ref'd

25 of 1229 operations

Clean

Generated public names do not collide

1229 operations clean

What to change first

The 7 heaviest of 8 rules that deducted.

  1. 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.

  2. 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.

  3. operationIds read as method names

    Name the id for the action, not the route. The audit suggests one per operation and can apply it. Inside Octri this one has a one-click fix.

  4. 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.

  5. Failure responses are declared

    Declare the failures you actually return, or one `default` response carrying your error shape.

  6. No duplicate or equivalent paths

    Keep one. A server routes both to the same handler, so the second is a duplicate method for your users.

  7. Authentication is described

    Declare the scheme you use, such as an http bearer or an apiKey header, and reference it from the operations it guards.

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 GitHub v3 REST API or Support.