Skip to content

Public docs spec: 31 endpoints carry sentence operationIds + no summary (legacy api-docs, not migrated to drf-spectacular) #76

Description

@betegon

Summary

After the operationId → token migration (sentry #117337 / #117339 / #117403, now in @sentry/api@0.228.0), 32 public endpoints still appear in openapi-derefed.json with sentence-style operationIds and no summary (e.g. "operationId": "List a Project's Issues", summary: null). This is not caused by that migration and does not affect the SDK — but it does affect the public API-reference docs, and it explains why these ops look "unmigrated."

Symptom

In openapi-derefed.json on main:

GET /api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/issues/
   operationId: "List a Project's Issues"
   summary:     null

vs. a properly-migrated op:

GET /api/0/organizations/{organization_id_or_slug}/issues/{issue_id}/
   operationId: "getOrganizationIssue"
   summary:     "Retrieve an Issue"

Root cause

Sentry's public spec is assembled from two systems:

  1. drf-spectacular @extend_schema decorators — only methods with publish_status = PUBLIC are emitted.
  2. The legacy hand-maintained api-docs/paths/**.json files in getsentry/sentry.

The 31 affected endpoints are published only through the legacy api-docs/ system. Their source publish_status is PRIVATE or EXPERIMENTAL, so they're excluded from the spectacular (decorator) output:

Endpoint group source publish_status
project issues (list / bulk mutate / bulk remove) all EXPERIMENTAL
project tags / tag keys PRIVATE
user feedback PRIVATE (# TODO: deprecate)
service hooks PRIVATE
external issues PRIVATE
org/project release files, org releases PRIVATE

The legacy api-docs/ files use sentence operationIds and carry no summary, so that's what ends up in the merged spec. The operationId token initiative only touched the spectacular-PUBLIC set (the 216 ops), which is correct — these were never in it.

Why the SDK is unaffected

@sentry/api names come from the normalizer (normalizeOperationId(method, path)) in build.mjs, which derives clean names from method+path regardless of the spec's operationId. So the SDK already exposes clean names for these endpoints (e.g. listProjectIssues). Consumers are not blocked. The gap is in the rendered API-reference docs (title/slug derived from summary/operationId).

Why this is not a regression

These endpoints have always shown sentence operationIds in the docs — that's how the legacy api-docs/ system works. Nothing regressed; the token migration simply didn't (and couldn't) cover them.

Fix (per endpoint, owner-gated, in getsentry/sentry)

This is the legacy api-docs/ → drf-spectacular migration, done per endpoint:

  1. Set the method(s) publish_status = ApiPublishStatus.PUBLIC (a deliberate public-API commitment — needs the owning team).
  2. Add a full @extend_schema(operation_id="<token>", summary="<old sentence>", parameters=..., responses=..., examples=...) at parity with the legacy file.
  3. Delete the legacy api-docs/paths/**.json file and its $ref in api-docs/openapi.json.
  4. Regenerate (make build-api-docs) and confirm the op now carries the token + summary.

Because step 1 is a public-API commitment, this can't be a blanket mechanical sweep — each endpoint needs its owning team's sign-off.

Affected endpoints (31, by legacy file)

events/project-issues.json                          List a Project's Issues; Bulk Mutate a List of Issues; Bulk Remove a List of Issues
events/tag-values.json + projects/tag-values.json   List a Tag's Values
projects/service-hooks.json                         List a Project's Service Hooks; Register a New Service Hook
projects/service-hook-details.json                  Retrieve / Update / Remove a Service Hook
projects/user-feedback.json                         List a Project's User Feedback; Submit User Feedback
integration-platform/sentry-app-installations.json  List an Organization's Integration Platform Installations
integration-platform/sentry-app-external-issues.json        Create or update an External Issue
integration-platform/sentry-app-external-issue-details.json Delete an External Issue
releases/organization-releases.json                 List an Organization's Releases; Create a New Release for an Organization
releases/organization-release-commits.json          List an Organization Release's Commits
releases/organization-release-commit-files.json     Retrieve Files Changed in a Release's Commits
releases/release-files.json                         List an Organization's Release Files; Upload a New Organization Release File
releases/release-file.json                          Retrieve / Update / Delete an Organization Release's File
releases/project-release-commits.json               List a Project Release's Commits
releases/project-release-files.json                 List a Project's Release Files; Upload a New Project Release File
releases/project-release-file.json                  Retrieve / Update / Delete a Project Release's File

Two special cases

  • Bulk Update Project Environments is NOT a legacy api-docs endpoint — it's a plain operation_id="Bulk Update Project Environments" literal in src/sentry/core/endpoints/project_environments.py that the token codemod missed. This one is a trivial operation_id → token rename in getsentry/sentry (no promotion needed).
  • Enable/Disable Spike Protection (api-docs/paths/projects/spike-protection.json): the legacy file is in sentry, but the endpoint implementation lives in getsentry, so the @extend_schema would be added there.

Verification

After each endpoint is migrated: make build-api-docs then confirm in tests/apidocs/openapi-derefed.json that the op shows the token operationId + summary (and that the path/shape is unchanged). The published spec re-syncs here via the openapi workflow.


Filed from analysis during the operationId token migration. SDK at @sentry/api@0.228.0 already exposes clean names for these endpoints; this issue tracks closing the docs-side gap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions