docs(docs): migrate GET /api/ai/models#177
Conversation
…-info Adds OpenAPI specs and reference pages for misc-reads endpoints landing on api as part of the chat to api migration. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis pull request introduces documentation for two new API endpoints: an AI models endpoint ( Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
3 issues found across 7 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="api-reference/openapi/youtube.json">
<violation number="1" location="api-reference/openapi/youtube.json:72">
P2: This spec is marked as OpenAPI 3.1.0 but still uses `nullable: true`; in 3.1, nullable fields should be modeled with `type` including `"null"` (or `oneOf`).</violation>
</file>
<file name="api-reference/openapi/email.json">
<violation number="1" location="api-reference/openapi/email.json:18">
P1: This endpoint performs a write (`upserts a contact`) but is modeled as GET with query params. Use a non-GET method (typically POST) with a request body for the email to avoid unintended side effects and URL-based PII exposure.</violation>
<violation number="2" location="api-reference/openapi/email.json:44">
P2: Do not document upstream failures as 400. Keep 400 for invalid input and add a 5xx response for Loops/upstream errors so clients can handle retries and error classification correctly.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (3)
api-reference/openapi/email.json (1)
18-20: Explicitly declare this endpoint as unauthenticated withsecurity: [].Given this is public, adding an explicit empty security requirement avoids accidental auth inheritance if a global scheme is introduced later.
Suggested change
"/api/email": { "get": { + "security": [], "description": "Fire-and-forget email tracking endpoint that upserts a contact in Loops. Used to track sign-ups and other lifecycle events. No authentication required.",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/email.json` around lines 18 - 20, Add an explicit empty security requirement to the public GET operation to prevent auth inheritance: update the "get" operation object for the email tracking endpoint to include security: [] (the GET operation key named "get") so the endpoint is explicitly unauthenticated even if a global security scheme is later introduced.api-reference/openapi/ai.json (1)
18-20: Add explicit unauthenticated security metadata for this operation.Please set
security: []on theGET /api/ai/modelsoperation to make public access explicit in the spec.Suggested change
"/api/ai/models": { "get": { + "security": [], "description": "Returns the catalog of language models available through the Vercel AI Gateway. Embedding models are filtered out. The full schema mirrors the Vercel AI Gateway response (`GatewayLanguageModelEntry` from `@ai-sdk/gateway`); the documented properties below are the load-bearing fields used by clients. No authentication required.",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/ai.json` around lines 18 - 20, The GET operation object for the /api/ai/models path is missing explicit unauthenticated metadata; update the operation (the "get" object under the /api/ai/models path in ai.json) to include security: [] so the spec explicitly marks this endpoint as public (keep the existing description and responses intact).api-reference/openapi/youtube.json (1)
18-20: Declare unauthenticated access explicitly on this operation.Adding
security: []makes the public contract explicit and avoids accidental auth inheritance later.Suggested change
"/api/youtube/channel-info": { "get": { + "security": [], "description": "Fetches the YouTube channel summary for an artist using their stored OAuth tokens. Returns the channel's snippet, statistics, and branding fields. The response always uses HTTP 200 (errors are surfaced via the `tokenStatus` field) except for missing-parameter requests, which return 400.",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/youtube.json` around lines 18 - 20, The GET operation for fetching a YouTube channel (the "get" operation) should explicitly declare unauthenticated access by adding "security": [] to the operation object; update the operation JSON (the object that contains "description" and "parameters") to include "security": [] so it won't inherit any global security requirements.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@api-reference/youtube/channel-info.mdx`:
- Line 3: The frontmatter key "openapi" contains the spec file path plus
method/path; update its value to only the required METHOD and path string (e.g.,
"GET /api/youtube/channel-info") so the openapi frontmatter matches the
project's format; locate the "openapi" frontmatter entry in this MDX and remove
the leading spec file path portion, leaving just the method and path.
---
Nitpick comments:
In `@api-reference/openapi/ai.json`:
- Around line 18-20: The GET operation object for the /api/ai/models path is
missing explicit unauthenticated metadata; update the operation (the "get"
object under the /api/ai/models path in ai.json) to include security: [] so the
spec explicitly marks this endpoint as public (keep the existing description and
responses intact).
In `@api-reference/openapi/email.json`:
- Around line 18-20: Add an explicit empty security requirement to the public
GET operation to prevent auth inheritance: update the "get" operation object for
the email tracking endpoint to include security: [] (the GET operation key named
"get") so the endpoint is explicitly unauthenticated even if a global security
scheme is later introduced.
In `@api-reference/openapi/youtube.json`:
- Around line 18-20: The GET operation for fetching a YouTube channel (the "get"
operation) should explicitly declare unauthenticated access by adding
"security": [] to the operation object; update the operation JSON (the object
that contains "description" and "parameters") to include "security": [] so it
won't inherit any global security requirements.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 19db342e-1872-44ef-a16f-b1b640906ff8
📒 Files selected for processing (7)
api-reference/ai/models.mdxapi-reference/email/track.mdxapi-reference/openapi/ai.jsonapi-reference/openapi/email.jsonapi-reference/openapi/youtube.jsonapi-reference/youtube/channel-info.mdxdocs.json
| @@ -0,0 +1,4 @@ | |||
| --- | |||
| title: 'Channel Info' | |||
| openapi: '/api-reference/openapi/youtube.json GET /api/youtube/channel-info' | |||
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, let's verify the file exists and see its actual content
cat -n api-reference/youtube/channel-info.mdx 2>/dev/null || echo "File not found"Repository: recoupable/docs
Length of output: 1881
🏁 Script executed:
# Search for other openapi frontmatter usages in the api-reference directory
find api-reference -name "*.mdx" -type f | head -20Repository: recoupable/docs
Length of output: 1881
🏁 Script executed:
# Check the structure and existing openapi patterns in the project
rg "openapi:\s*" api-reference --no-heading -A 0 | head -20Repository: recoupable/docs
Length of output: 1881
openapi frontmatter should be method/path only.
Current value includes the spec file path and does not match the project's required format of METHOD /path.
Suggested change
-openapi: '/api-reference/openapi/youtube.json GET /api/youtube/channel-info'
+openapi: 'GET /api/youtube/channel-info'📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| openapi: '/api-reference/openapi/youtube.json GET /api/youtube/channel-info' | |
| openapi: 'GET /api/youtube/channel-info' |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@api-reference/youtube/channel-info.mdx` at line 3, The frontmatter key
"openapi" contains the spec file path plus method/path; update its value to only
the required METHOD and path string (e.g., "GET /api/youtube/channel-info") so
the openapi frontmatter matches the project's format; locate the "openapi"
frontmatter entry in this MDX and remove the leading spec file path portion,
leaving just the method and path.
- replace OpenAPI 3.0 nullable:true with 3.1 type:[..., "null"] arrays - email.json: split 400 (validation) from 500 (upstream/internal) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reflects the api-side change: email tracking upserts a Loops contact (a write) and now takes a JSON body instead of a URL query param. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| @@ -0,0 +1,4 @@ | |||
| --- | |||
| title: 'Track Email' | |||
| openapi: '/api-reference/openapi/email.json POST /api/email' | |||
There was a problem hiding this comment.
YAGNI principle - Where is this endpoint being used?
Loops is no longer used; the email tracking endpoint is removed from this migration entirely. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
api-reference/openapi/youtube.json (1)
59-97: UseoneOfto separate success and failure response variants.The current schema is structurally ambiguous—it allows
success=truewithoutchannels, orsuccess=falsewithout anerrorfield. Splitting into explicitoneOfvariants (one requiringchannels, the other requiringerror) makes generated types safer and eliminates invalid states.This pattern is already used in
social.jsonandreleases.json, and the codebase runs on OpenAPI 3.1.0, which supports it.Proposed schema shape
"YouTubeChannelInfoResponse": { - "type": "object", - "required": ["success", "tokenStatus"], - "properties": { - "success": { "type": "boolean" }, - "channels": { "type": ["array", "null"], "items": { "$ref": "#/components/schemas/YouTubeChannelData" } }, - "tokenStatus": { "type": "string", "enum": ["valid","invalid","missing_param","api_error","error"] }, - "error": { "type": "string" }, - "details": { "type": "string" } - } + "oneOf": [ + { + "type": "object", + "required": ["success", "tokenStatus", "channels"], + "properties": { + "success": { "const": true }, + "tokenStatus": { "const": "valid" }, + "channels": { + "type": "array", + "items": { "$ref": "#/components/schemas/YouTubeChannelData" } + } + } + }, + { + "type": "object", + "required": ["success", "tokenStatus", "error"], + "properties": { + "success": { "const": false }, + "tokenStatus": { "type": "string", "enum": ["invalid","missing_param","api_error","error"] }, + "error": { "type": "string" }, + "details": { "type": "string" }, + "channels": { "type": "null" } + } + } + ] }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@api-reference/openapi/youtube.json` around lines 59 - 97, YouTubeChannelInfoResponse is ambiguous because it allows inconsistent combinations of success/channels/error; refactor the schema to use oneOf with two explicit variants: a success variant (YouTubeChannelInfoResponseSuccess) that requires success=true and channels (and tokenStatus) and disallows error/details, and a failure variant (YouTubeChannelInfoResponseError) that requires success=false, error (and tokenStatus) and may include details but disallows channels; update the YouTubeChannelInfoResponse ref to oneOf those variants and keep the existing YouTubeChannelData schema unchanged so generated types enforce the valid states.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@api-reference/openapi/youtube.json`:
- Around line 1-16: The OpenAPI document is missing a security contract; add a
components.securitySchemes section (e.g., an API Key or HTTP Bearer scheme) and
then declare either a global "security" array (to apply to all operations) or
per-operation "security" entries under "paths" to make authentication explicit;
update the top-level keys (openapi/info/servers/paths) by inserting
"components.securitySchemes" and a top-level "security" reference to the scheme
name (or annotate specific operations in "paths") so CI checks CKV_OPENAPI_4/5
pass and consumers know the auth requirement.
---
Nitpick comments:
In `@api-reference/openapi/youtube.json`:
- Around line 59-97: YouTubeChannelInfoResponse is ambiguous because it allows
inconsistent combinations of success/channels/error; refactor the schema to use
oneOf with two explicit variants: a success variant
(YouTubeChannelInfoResponseSuccess) that requires success=true and channels (and
tokenStatus) and disallows error/details, and a failure variant
(YouTubeChannelInfoResponseError) that requires success=false, error (and
tokenStatus) and may include details but disallows channels; update the
YouTubeChannelInfoResponse ref to oneOf those variants and keep the existing
YouTubeChannelData schema unchanged so generated types enforce the valid states.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: a7be631b-2153-457d-b2b3-d679e63f48b8
📒 Files selected for processing (2)
api-reference/openapi/youtube.jsondocs.json
🚧 Files skipped from review as they are similar to previous changes (1)
- docs.json
Mirrors the api response cleanup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop the `success` field from the YouTube channel-info OpenAPI schema;
align with the api-side `{ status: "success", channels }` envelope.
Re-auth requirement is now signalled by `channels: null`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
PR #174's nav structure was written Apr 27, before three pages were added to main: - api-reference/ai/models (added by #177 on May 1) - api-reference/sessions/create (added by #186 on May 3) - api-reference/sessions/get (added by #185 on May 4) These pages exist on disk but had no nav entry in the combined PR, which would orphan them once #189 lands. Adding them in: - Accounts tab → new "Sessions" group placed after "Sandboxes" (matches main's grouping of sessions with sandboxes) - Chat tab → new "Models" group at the end (closest semantic fit; main grouped this under "Tools & Reference" which doesn't exist in our restructured 9-tab layout) Co-authored-by: Cursor <cursoragent@cursor.com>
Spotted by a rendered-page review. Two pages had outdated or misleading content that needed correction: index.mdx: - "any of the 40+ endpoints" -> "130+ endpoints" (actual: 137 across all 7 OpenAPI specs) - "running a label" -> "running a music business" (matches the homepage lead paragraph that was already broadened) - Artists card: removed "and comments" — that endpoint was deleted in f896bc7 because it has no API handler. Card now reads "browse fans and posts" - Artists / Catalog cards: "your label" -> "your roster" (consistent with broader audience framing) - Content card: "7 endpoints" -> "11 endpoints" (7 primitives + create, estimate, validate, templates) - Quickstart bullet vs Quickstart Guides card: now both say "Under a minute" (was inconsistent — one said "~5 minutes") - For AI agents OpenAPI table: added rows for ai.json (added by main #177) and sessions.json (added by main #185-187). Was missing 2 of 7 specs. mcp.mdx: - Reframe the "Org-scoped keys can target any account... Personal API keys can only operate on their own data" callout. The phrasing implied two key types exist, which is wrong — there's only one key type, and access is determined by the OWNER ACCOUNT's organization membership. New phrasing matches /authentication's access rules and explicitly says there's no separate "org-scoped" key type. Links out to /authentication#access-control for the full ladder.
Summary
Adds an OpenAPI spec and Mintlify page for
/api/ai/models, ahead of the api-side parity landing.Test plan
jq empty).npx mintlify@latest devand the nav link is clickable.