Skip to content

docs(api-reference): fix Developer Portal OpenAPI spec gaps found in audit - #194

Merged
soamdesai-tfh merged 5 commits into
mainfrom
docs-audit/openapi-developer-portal-fixes
Sep 24, 2026
Merged

soamdesai-tfh merged 5 commits into
mainfrom
docs-audit/openapi-developer-portal-fixes

Conversation

@soamdesai-tfh

@soamdesai-tfh soamdesai-tfh commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Fix Developer Portal OpenAPI spec.

  • Add security + 401 responses to 4 API-key operations that looked unauthenticated (send-notification, transaction/debug, create-action, user-grant-cycle).
  • Add sandbox to the verify environment enum; add face to verification_level.
  • Document the GraphQL auth requirement; mark precheck's example app_id as illustrative and add its 404.
  • Make SendNotificationRequest's branches match the server's precedence (a body with localisations is localized); document mini_app_path's format and app_id match.
  • Add missing 400/401/403/404/426 responses across several operations, matching the routes' error codes; fix the GraphQL error examples.
  • Remove orphaned CreditBorrower/CreditError schemas; document JWKS caching (refetch on an unknown kid, bounded TTL).

- Finding 1 (CRITICAL): add security: [{bearerAuth: []}] to send-notification,
  create-action/{app_id}, and transaction/debug operations, plus documented 401
  responses for missing API key
- Finding 2 (HIGH): add "sandbox" to the environment enum in all four
  VerifyV4*Request/Response schemas to match live /api/v4/verify behavior
- Finding 3 (HIGH): add "face" to VerifyProofRequest.verification_level enum,
  matching the field's own description and live server behavior
- Finding 4 (HIGH): note in the GraphQL proxy operation description that the
  example query requires authentication and that unauthenticated calls return
  200 with a GraphQL-level error, not a 401
- Finding 5 (HIGH): mark the precheck 200 example app_id as illustrative-only
  and document the real 404 (app not found/inactive) response
- Finding 6 (HIGH): add additionalProperties: false to both SendNotificationRequest
  oneOf branches so legacy and localized payloads are mutually exclusive
- Finding 7 (HIGH): document accepted mini_app_path deeplink formats and replace
  the placeholder example value with a valid worldapp:// deeplink
- Finding 8 (MEDIUM): document the 426 AU-001 app-version gate on
  /public/v1/miniapps/prices
- Finding 9 (MEDIUM): document 400 (invalid transaction ID) on
  transaction/{transaction_id} and 401 (missing API key) on transaction/debug
- Finding 10 (MEDIUM): document the distinct 404 "API key not found" response
  on create-action and send-notification, noting how to disambiguate from an
  unrecognized app_id via the attribute field
- Finding 11 (MEDIUM): add ErrorResponse schema + example to the
  user-grant-cycle 400 response, consistent with the rest of the file
- Finding 12 (LOW): remove orphaned CreditBorrower/CreditError schemas that no
  path in this spec references
- Finding 13 (LOW): document JWKS caching/rate-limit behavior on /api/v1/jwks
@mintlify

mintlify Bot commented Sep 21, 2026 •

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated
world 🟢 Ready View Preview Sep 23, 2026, 10:06 PM

💡 Tip: Enable Automations to automatically generate PRs for you.

@soamdesai-tfh

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 21, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-21T04:10:39.928024Z e3cd28f Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3cd28fc18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread openapi/developer-portal.json Outdated
"get": {
"summary": "Get JWK Keys",
"description": "Retrieve JWKs (public keys) used to verify JWT signatures for verification requests.",
"description": "Retrieve JWKs (public keys) used to verify JWT signatures for verification requests. This response is not edge-cached (no `Cache-Control`, `ETag`, or `Expires` headers are set) and no dedicated rate limit is published for this endpoint. Clients should cache the JWKS response client-side and only refetch on a `kid` cache miss, rather than re-fetching on every signature verification.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Bound the JWKS cache lifetime

If a signing key is removed from the JWKS because it was compromised or revoked, the advice to refresh only on a kid miss lets clients retain and trust that removed key indefinitely: forged tokens using the cached kid never trigger a miss. Recommend a bounded refresh interval or TTL in addition to refreshing on unknown keys.

Useful? React with 👍 / 👎.

Comment thread openapi/developer-portal.json Outdated
}
}
},
"additionalProperties": false

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow mixed notification payloads in the localized branch

When a caller follows the schema description and supplies localisations together with legacy title/message, this additionalProperties: false rejects the legacy fields, while the other branch rejects localisations; consequently the payload matches neither oneOf branch instead of using the localized content as documented. The localized branch should permit the legacy fields as optional properties, or the union should otherwise encode the stated precedence.

Useful? React with 👍 / 👎.

Trims over-explaining response/description text added in this PR
(precheck 200/404, jwks, graphql, notification 404s, 426 gate) to the
repo's terser Mintlify style, and drops the undeclared `app_id` field
from the precheck 404 example so it matches the ErrorResponse schema.
@soamdesai-tfh

Copy link
Copy Markdown
Contributor Author

Follow-up polish pass: tightened the over-explained descriptions this PR added (precheck 200/404, jwks, graphql, notification 404s, 426 client-gate) to match the repo's terser house style, and removed the undeclared app_id field from the precheck 404 example so it matches the ErrorResponse schema exactly. No functional/schema changes; python3 -m json.tool still passes.

- JWKS caching guidance (P1): refetch-on-kid-miss alone never detects
  a key that was revoked/rotated out — a client that already has it
  cached would trust it indefinitely, since removal never produces a
  miss. Added a bounded TTL requirement alongside the kid-miss refetch.
- SendNotificationRequest oneOf (P2): the schema's own description
  says a payload with both title/message and localisations uses the
  localized content, but additionalProperties: false on both oneOf
  branches meant such a payload satisfied NEITHER branch. Added
  title/message as optional (ignored) properties on the localized
  branch so it's the sole match, matching the documented precedence.
  Verified with a real Draft7 jsonschema validator: legacy-only,
  localized-only, and combined payloads each now validate with zero
  errors against exactly one branch.
- send-notification, create-action, transaction/debug: document 400
  api_key_inactive, 403 invalid_app/invalid_api_key, and the real 404
  causes
- user-grant-cycle: add bearerAuth security and its API key responses
- graphql: fix the unauthenticated example error, relabel 401 as a
  rejected api_ key, replace 415 with the real 400s
- SendNotificationRequest: exclude localisations from the legacy branch
  with not/required instead of additionalProperties: false; reword the
  precedence note
- mini_app_path: app_id must match the request's app_id
- Use 42-character example wallet addresses; fix the user-grant-cycle
  and precheck 400 examples
- Tighten the JWKS caching note; add optional app_id/team_id to
  ErrorResponse
@soamdesai-tfh
soamdesai-tfh merged commit c1607d6 into main Sep 24, 2026
9 checks passed
@soamdesai-tfh
soamdesai-tfh deleted the docs-audit/openapi-developer-portal-fixes branch September 24, 2026 00:11

This branch was successfully deployed

1 active deployment
staging — 564e80fa Deployed Sep 23, 2026 by mintlify[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants