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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions