Skip to content

fix: harden research API response schemas and add error responses#101

Open
sidneyswift wants to merge 6 commits intomainfrom
fix/research-response-schemas
Open

fix: harden research API response schemas and add error responses#101
sidneyswift wants to merge 6 commits intomainfrom
fix/research-response-schemas

Conversation

@sidneyswift
Copy link
Copy Markdown
Contributor

@sidneyswift sidneyswift commented Apr 5, 2026

Summary

  • Fix field name/type mismatches in 4 research response schemas by cross-referencing actual API handler code
  • Add reusable ResearchErrorResponse component ({ status: "error", error: "message" })
  • Add 400 and 401 error responses to all 30 research endpoints via $ref
  • Add example: "success" to all response schema status fields for consistency

Schema fixes

Schema Change Reason
ResearchCareerResponse datacareer Handler returns { career: data }, not { data }
ResearchWebResponse items contentsnippet; added date, last_updated Perplexity returns snippet, not content
ResearchEnrichResponse Flattened research_basis.citations → top-level citations Handler returns { output, citations } flat
ResearchPeopleResult Added id, publishedDate, author Exa search returns these fields

Error responses added

All 30 /api/research/* endpoints now document:

  • 400 — Validation errors (missing params, invalid values)
  • 401 — Authentication failures (invalid/missing API key)

Both reference the shared ResearchErrorResponse schema.

Test plan

  • Verify openapi.json parses as valid JSON (done locally)
  • Verify Mintlify renders all 30 research endpoint docs correctly
  • Phase 3: Hit each endpoint with live requests and compare response shape to schema

Made with Cursor

Summary by CodeRabbit

  • Documentation
    • Clarified CLI wording and examples for deep research and radio commands; documented standardized 400/401 JSON error responses and a shared research error schema.
  • New Features
    • Strengthened research API request parameter constraints (country format, enums/defaults, boolean latest) and added chart query defaults.
    • Expanded and reorganized research responses: richer audience/career breakdowns, consolidated identifiers, moved citations to top-level, renamed social fields and added reels, added timestamps/authors, required status/results and standardized status examples.

- Fix ResearchCareerResponse: rename `data` → `career` to match handler
- Fix ResearchWebResponse: rename `content` → `snippet`, add `date` and
  `last_updated` fields to match Perplexity search results
- Fix ResearchEnrichResponse: flatten `research_basis.citations` → top-level
  `citations` to match handler output
- Fix ResearchPeopleResult: add missing `id`, `publishedDate`, `author` fields
  from Exa search results
- Add `example: "success"` to all response schema `status` fields
- Create reusable `ResearchErrorResponse` component schema
- Add 400 (validation) and 401 (auth) error responses to all 30 research
  endpoints referencing ResearchErrorResponse via $ref

Made-with: Cursor
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 5, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Updated the OpenAPI spec to standardize 400/401 error responses for /api/research/* with a new ResearchErrorResponse, tightened and renamed multiple Research* response/request schemas (field renames, nesting, required/nullable additions, examples), adjusted /api/research/charts query params, and small CLI doc text updates for research commands.

Changes

Cohort / File(s) Summary
OpenAPI root
api-reference/openapi.json
Extensive edits to research endpoints and components: added standardized error responses, numerous schema shape changes, examples, required/nullable updates, and query parameter constraints.
Error schema & responses
api-reference/openapi.json
Added components.schemas.ResearchErrorResponse (required status, error, status enum "error") and referenced it for documented 400 and 401 responses across research endpoints.
Charts endpoint params
api-reference/openapi.json
/api/research/charts query params refined: country constrained to ISO format with default US; interval default daily; type default regional (enum); latest converted to boolean default true.
Audience & demographics
api-reference/openapi.json
ResearchAudienceResponse restructured: removed legacy age/gender/countries fields in favor of audience_genders, audience_genders_per_age, top_countries, top_cities, audience_brand_affinities; added status.example.
Career, people & lookup
api-reference/openapi.json
ResearchCareerResponse now exposes career (removed career_stage/data, removed permissive additionalProperties); ResearchPeopleResult adds optional id, nullable publishedDate/author, nullable highlights; ResearchLookupResponse nests cross-platform ids under data.
Enrich & extract
api-reference/openapi.json
ResearchEnrichRequest schema constrained to require top-level type: "object" and properties/required; ResearchEnrichResponse moved citations to top-level; ResearchExtractResponse adds required: ["status","results"] and refines errors description.
Instagram, web & media responses
api-reference/openapi.json
ResearchInstagramPostsResponse: renamed poststop_posts, added top_reels; ResearchWebResponse: contentsnippet, added nullable date and last_updated.
Misc Research schemas*
api-reference/openapi.json
Added status.example: "success" and small metadata tweaks across many Research*Response schemas (albums, charts, cities, deep, discover, extract, festivals, genres, insights, lookup, metrics, milestones, people, playlists, profile, radio, rank, search, similar, tracks, urls, venues, etc.).
Documentation / CLI
cli.mdx
Renamed “Deep research report” to “Deep web research”; updated example subcommand from recoup research report "<prompt>" to recoup research deep "<prompt>"; minor description text changes for rank/radio commands.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • sweetmantech

Poem

🐰 I hopped through schemas, tidy and bright,

Lifted citations up into light,
Renamed a field and tightened a rule,
Errors now speak when inputs aren't cool,
A rabbit cheers this API's new flight.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: hardening research API response schemas and adding error response documentation.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/research-response-schemas

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
api-reference/openapi.json (1)

7144-7165: ⚠️ Potential issue | 🟡 Minor

Keep the endpoint prose aligned with the declared schema fields.

Line 7144 says the profile response includes social URLs and career stage, but ResearchProfileResponse does not declare those fields. Line 7390 similarly promises popularity and platform IDs that ResearchTrackResponse does not expose. Either add the fields explicitly or trim the descriptions; additionalProperties: true will not make them discoverable in Mintlify or generated clients.

Also applies to: 7390-7411, 15712-15758, 15909-15938

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 7144 - 7165, Endpoint descriptions
claim fields (e.g., social URLs, career stage, popularity, platform IDs) that
are not declared on the corresponding response schemas; update the OpenAPI spec
so the prose matches the schemas by either (A) adding the missing properties to
the referenced schemas (e.g., ResearchProfileResponse, ResearchTrackResponse)
with proper types and descriptions, or (B) removing/trimming those claims from
the endpoint descriptions; do not rely on additionalProperties: true to
communicate these fields, and ensure any added properties are documented in the
schema so generated clients and Mintlify can discover them.
🧹 Nitpick comments (1)
api-reference/openapi.json (1)

14939-14948: Verify whether the research 200 schemas are now success-only.

Line 14942 still permits status: "error", while Lines 14962, 15218, and 16069 no longer constrain the field beyond string. If the new ResearchErrorResponse is meant to cover the remaining error paths, these 200 schemas can be tightened to enum: ["success"]; otherwise the 200-error variant should be modeled explicitly instead of leaving the contract inconsistent across endpoints.

Possible tightening if 200 responses are success-only
          "status": {
            "type": "string",
-            "enum": [
-              "success",
-              "error"
-            ],
+            "enum": [
+              "success"
+            ],
            "example": "success"
          },

Please confirm this against the live-response validation step before applying it across all research success schemas.

Also applies to: 14958-14965, 15109-15120, 15215-15220, 16065-16071

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 14939 - 14948, Confirm whether 200
responses for research endpoints are intended to be success-only; if so, tighten
the ResearchAlbumsResponse and sibling 200-level response schemas (e.g., the
Research*Response objects referenced around ResearchAlbumsResponse) by changing
their "status" enum to ["success"] (apply same change to the other occurrences
you noted), otherwise add an explicit 200-level error variant instead of leaving
"status" as an unconstrained string; verify the decision against the
live-response validation step before applying the change and ensure consistency
with the ResearchErrorResponse model used for non-200 error paths.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@api-reference/openapi.json`:
- Around line 7144-7165: Endpoint descriptions claim fields (e.g., social URLs,
career stage, popularity, platform IDs) that are not declared on the
corresponding response schemas; update the OpenAPI spec so the prose matches the
schemas by either (A) adding the missing properties to the referenced schemas
(e.g., ResearchProfileResponse, ResearchTrackResponse) with proper types and
descriptions, or (B) removing/trimming those claims from the endpoint
descriptions; do not rely on additionalProperties: true to communicate these
fields, and ensure any added properties are documented in the schema so
generated clients and Mintlify can discover them.

---

Nitpick comments:
In `@api-reference/openapi.json`:
- Around line 14939-14948: Confirm whether 200 responses for research endpoints
are intended to be success-only; if so, tighten the ResearchAlbumsResponse and
sibling 200-level response schemas (e.g., the Research*Response objects
referenced around ResearchAlbumsResponse) by changing their "status" enum to
["success"] (apply same change to the other occurrences you noted), otherwise
add an explicit 200-level error variant instead of leaving "status" as an
unconstrained string; verify the decision against the live-response validation
step before applying the change and ensure consistency with the
ResearchErrorResponse model used for non-200 error paths.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6fbea925-cd8b-4724-bb3f-f6f6e2f21bb3

📥 Commits

Reviewing files that changed from the base of the PR and between 6c6d199 and e34e3e7.

📒 Files selected for processing (1)
  • api-reference/openapi.json

- Instagram posts: rename `posts` to `top_posts` + `top_reels`
- Lookup: wrap ID fields inside `data` object to match handler
- Audience: replace simplified `age`/`gender`/`countries` with actual
  Chartmetric fields (`audience_genders`, `audience_genders_per_age`,
  `top_countries`, `top_cities`, `audience_brand_affinities`)
- Extract: make `errors` field optional (only present on partial failure)
- Charts: document default values for country (US), interval (daily),
  type (regional), and latest (true) params
- Enrich: note that `schema.type: "object"` is required

Made-with: Cursor
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

No issues found across 1 file

@sidneyswift
Copy link
Copy Markdown
Contributor Author

Schema Verification Results

All 30 research endpoint response schemas have been verified against live API responses on the preview deployment.

Fixes applied in this PR

Schema Issue Fix
ResearchInstagramPostsResponse Docs had posts, API returns top_posts + top_reels Updated to match API
ResearchLookupResponse Docs had flat fields at root, API wraps in data object Moved fields inside data
ResearchAudienceResponse Docs had age, gender, countries, API returns audience_genders, audience_genders_per_age, top_countries, top_cities, ... Updated field names, added additionalProperties: true
ResearchExtractResponse errors was required, API only returns it on partial failures Made errors optional
ResearchCareerResponse Had data field, API returns career Renamed to career
ResearchEnrichResponse Nested research_basis.citations, API returns flat citations Flattened
ResearchWebResponse items Had content, API returns snippet Fixed field name, added date, last_updated
ResearchPeopleResult Missing fields from Exa Added id, publishedDate, author
All 30 endpoints No error responses documented Added 400 and 401 via shared ResearchErrorResponse

Verification

All 30 endpoints tested with cURL against the API preview — see api#366 comment for full results.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
api-reference/openapi.json (1)

6196-6200: ⚠️ Potential issue | 🟠 Major

latest query param type conflicts with its documented semantics

Line [6196] documents a boolean flag, but Lines [6198-6199] define it as a string with "default": "true". This creates contract ambiguity for generated clients.

🛠️ Proposed parameter schema fix
           "latest": {
             "in": "query",
             "required": false,
             "description": "Return only the latest chart. Defaults to `true`.",
             "schema": {
-              "type": "string",
-              "default": "true"
+              "type": "boolean",
+              "default": true
             }
           }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 6196 - 6200, The OpenAPI parameter
"latest" currently has a schema with "type": "string" and "default": "true",
which conflicts with its boolean semantics; update the "latest" parameter's
schema to use "type": "boolean" and set "default": true (a boolean, not a
string) so generated clients receive the correct contract for the "latest" query
param.
🧹 Nitpick comments (1)
api-reference/openapi.json (1)

14965-14968: Consider constraining success status fields to a fixed enum/const

These success-response schemas now use type: "string" with example: "success". For stricter contracts, prefer enum: ["success"] (or const: "success"), especially since this PR is hardening API schemas.

Also applies to: 15016-15019, 15240-15243, 16124-16127

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 14965 - 14968, Replace the loose
"status" property schemas that are currently "type": "string" with a fixed value
(use either "const": "success" or "enum": ["success"]) in each response schema
where "status" is always "success" (the "status" property definitions in the
response schema objects shown in the diff and the other occurrences noted).
Update the example if necessary to match the chosen const/enum and keep the
schema consistent across the other occurrences mentioned.
🤖 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.json`:
- Around line 6489-6490: The OpenAPI contract doesn't enforce the documented
requirement that ResearchEnrichRequest.schema must be an object; update the
OpenAPI schema for ResearchEnrichRequest (the property named "schema" on
ResearchEnrichRequest) to require a top-level "type": "object" (or an equivalent
"const" constraint) so generated validators/SDKs reject non-object
schemas—modify the ResearchEnrichRequest.schema definition where
components/schemas define it (the entries labeled ResearchEnrichRequest and its
"schema" property) to include "type": "object" and, if applicable, add
"required": ["schema"]/explicit validation keywords to ensure the constraint is
enforced.

---

Outside diff comments:
In `@api-reference/openapi.json`:
- Around line 6196-6200: The OpenAPI parameter "latest" currently has a schema
with "type": "string" and "default": "true", which conflicts with its boolean
semantics; update the "latest" parameter's schema to use "type": "boolean" and
set "default": true (a boolean, not a string) so generated clients receive the
correct contract for the "latest" query param.

---

Nitpick comments:
In `@api-reference/openapi.json`:
- Around line 14965-14968: Replace the loose "status" property schemas that are
currently "type": "string" with a fixed value (use either "const": "success" or
"enum": ["success"]) in each response schema where "status" is always "success"
(the "status" property definitions in the response schema objects shown in the
diff and the other occurrences noted). Update the example if necessary to match
the chosen const/enum and keep the schema consistent across the other
occurrences mentioned.
🪄 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: d92d3c9d-aed5-40ac-8715-3900782c23eb

📥 Commits

Reviewing files that changed from the base of the PR and between e34e3e7 and b73379b.

📒 Files selected for processing (2)
  • api-reference/openapi.json
  • cli.mdx

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
cli.mdx (1)

350-355: ⚠️ Potential issue | 🟡 Minor

Generalize the description to match the examples without artist argument.

Line 350 says "playing an artist's music" (implying artist-scoped behavior), but the examples on lines 353-354 show no artist argument, and the command is not listed among the artist-scoped commands documented in the file. Either clarify that the command works without an artist parameter (e.g., "List popular radio stations") or add artist argument examples if it supports filtering by artist.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cli.mdx` around lines 350 - 355, The description "playing an artist's music"
is inconsistent with the examples for the CLI command recoup research radio;
either generalize the sentence to match the examples (e.g., change the short
description to "List radio stations" or "List popular radio stations") or, if
the command supports an artist filter, add example usages showing the artist
argument (e.g., recoup research radio "<artist name>" and recoup research radio
"<artist name>" --json). Update the CLI doc string that references the command
name recoup research radio accordingly so the description and examples are
aligned.
🧹 Nitpick comments (1)
cli.mdx (1)

379-381: Trim repetitive phrasing in the deep section title/lead.

“Deep web research” is repeated in both the heading and sentence; this can be tighter for scanability.

✂️ Suggested wording
-### Deep web research
-
-Deep web research that synthesizes information from across the web into a cited report.
+### Deep research
+
+Synthesize information from across the web into a cited report.

As per coding guidelines, "Keep documentation content concise and scannable" and "Use clear, self-documenting titles and descriptions in documentation."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cli.mdx` around lines 379 - 381, The heading "### Deep web research" and the
lead sentence repeat the phrase; update either the heading or the sentence to
remove duplication for conciseness — e.g., keep the heading "### Deep web
research" and change the lead to a tighter description like "Synthesizes
information from across the web into a cited report" or change the heading to
"### Deep research" and keep the original lead; apply this edit to the "### Deep
web research" heading and its following lead sentence to improve scanability.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@cli.mdx`:
- Around line 350-355: The description "playing an artist's music" is
inconsistent with the examples for the CLI command recoup research radio; either
generalize the sentence to match the examples (e.g., change the short
description to "List radio stations" or "List popular radio stations") or, if
the command supports an artist filter, add example usages showing the artist
argument (e.g., recoup research radio "<artist name>" and recoup research radio
"<artist name>" --json). Update the CLI doc string that references the command
name recoup research radio accordingly so the description and examples are
aligned.

---

Nitpick comments:
In `@cli.mdx`:
- Around line 379-381: The heading "### Deep web research" and the lead sentence
repeat the phrase; update either the heading or the sentence to remove
duplication for conciseness — e.g., keep the heading "### Deep web research" and
change the lead to a tighter description like "Synthesizes information from
across the web into a cited report" or change the heading to "### Deep research"
and keep the original lead; apply this edit to the "### Deep web research"
heading and its following lead sentence to improve scanability.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3780ae11-b0d2-4294-8414-ef0f1c558cd0

📥 Commits

Reviewing files that changed from the base of the PR and between b73379b and 8cd0bf2.

📒 Files selected for processing (1)
  • cli.mdx

Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

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="cli.mdx">

<violation number="1" location="cli.mdx:350">
P1: Custom agent: **Flag AI Slop and Fabricated Changes**

This description claims the endpoint lists radio stations "playing an artist's music," but the OpenAPI spec explicitly marks this endpoint as **NOT artist-scoped** and the CLI example takes no artist argument. Revert to something accurate like the original or the spec's own description: "List radio stations tracked by Chartmetric."</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.

@sidneyswift
Copy link
Copy Markdown
Contributor Author

Addressing review comments

1. Profile/metrics descriptions promise fields not in schema (CodeRabbit, minor)
The profile and metrics schemas use additionalProperties: true because Chartmetric returns 30+ fields that vary. The descriptions mention common fields as examples — the schema allows any field. No change needed.

2. latest param type conflicts (CodeRabbit, major)
Fixed — changed from type: string, default: "true" to type: boolean, default: true.

3. Enrich schema doesn't enforce type: "object" (CodeRabbit, major)
Fixed — added required: ["type", "properties"] with type constrained to enum: ["object"].

4. Radio description inaccurate (Cubic, P1)
Fixed — changed from "playing an artist's music" to "List tracked radio stations."

All fixes in commit 57a4652.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
api-reference/openapi.json (2)

5967-5986: Consider using reusable response components for repeated 400/401 blocks

The same 400/401 response objects are repeated across all research operations. Centralizing them under components.responses will reduce duplication and prevent drift.

♻️ Example refactor pattern
+ "components": {
+   "responses": {
+     "ResearchValidationError": {
+       "description": "Validation error",
+       "content": {
+         "application/json": {
+           "schema": {
+             "$ref": "#/components/schemas/ResearchErrorResponse"
+           }
+         }
+       }
+     },
+     "ResearchAuthError": {
+       "description": "Authentication failed — invalid or missing API key",
+       "content": {
+         "application/json": {
+           "schema": {
+             "$ref": "#/components/schemas/ResearchErrorResponse"
+           }
+         }
+       }
+     }
+   }
+ }
- "400": { ...ResearchErrorResponse... },
- "401": { ...ResearchErrorResponse... }
+ "400": { "$ref": "#/components/responses/ResearchValidationError" },
+ "401": { "$ref": "#/components/responses/ResearchAuthError" }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 5967 - 5986, The OpenAPI spec
repeats identical 400 and 401 response objects for research endpoints; refactor
by creating reusable entries under components.responses (e.g.,
components.responses.ResearchBadRequest and components.responses.Unauthorized or
similar) that reference the existing ResearchErrorResponse schema and then
replace each inline "400" and "401" response block with $ref pointers to those
new components; update any operation objects that currently embed the repeated
blocks to use these component refs to remove duplication and keep semantics
identical.

14965-14968: Keep status constrained in success response schemas

In several updated schemas, status became an unconstrained string with only an example. That loosens the contract and reduces SDK type safety. Prefer enum: ["success"] (or const: "success") for 200-success payloads.

✅ Example for one affected schema
"status": {
-  "type": "string",
-  "example": "success"
+  "type": "string",
+  "enum": ["success"],
+  "example": "success"
}

Also applies to: 15016-15019, 15258-15261, 15476-15478, 15531-15533, 16142-16145

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 14965 - 14968, The response schema
currently defines "status" as an unconstrained string with only an example;
update each affected success-response schema (e.g., the schema object that
contains the "status" property shown in this diff and the other listed
occurrences) to constrain it to the literal "success" by replacing the loose
string type with either "enum": ["success"] or "const": "success" so the OpenAPI
contract and generated SDK types reflect the fixed success value. Locate the
"status" property definitions in the shown schema and the other occurrences
(lines referenced in the comment) and change their definition accordingly,
keeping any existing example if desired.
cli.mdx (2)

379-381: Tighten repetitive “Deep web research” phrasing.

The heading and first sentence repeat the same wording; a shorter sentence improves scanability.

✏️ Suggested copy tweak
 ### Deep web research

-Deep web research that synthesizes information from across the web into a cited report.
+Synthesize web findings into a cited report.

As per coding guidelines, "Keep documentation content concise and scannable."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cli.mdx` around lines 379 - 381, The heading "Deep web research" and the
following sentence repeat the same phrase; remove the redundancy by shortening
the sentence under the "Deep web research" heading to a concise descriptor
(e.g., "Synthesizes information from across the web into a cited report.") so
the heading remains and the body becomes a single scannable line; update the
sentence text beneath the "Deep web research" heading to the concise version and
remove the original repetitive sentence.

350-350: Consider making radio scope explicit.

“List tracked radio stations” is fine, but “List globally tracked radio stations” is slightly clearer at a glance.

As per coding guidelines, "Use clear, self-documenting titles and descriptions in documentation."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cli.mdx` at line 350, Update the documentation string "List tracked radio
stations" to explicitly indicate scope by changing it to "List globally tracked
radio stations" wherever the exact phrase appears (e.g., the title or
description in the CLI docs entry that currently reads "List tracked radio
stations") so the command description is self-documenting and unambiguous;
ensure the modified phrase is used consistently in the CLI help/MDX entry and
keep formatting identical to surrounding lines.
🤖 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.json`:
- Around line 6166-6190: The schemas for the query parameters "country",
"interval", and "type" lack the constraints described in their descriptions;
update the parameter schemas in openapi.json for the "country" parameter to
enforce a two-letter ISO code (e.g., add minLength: 2, maxLength: 2 and a
pattern like two alphabetic chars) and update "interval" and "type" to use
explicit enums (interval: ["daily","weekly"]; type: ["regional","viral"]) so
generated validators/SDKs will enforce the documented constraints; locate the
parameter objects named "country", "interval", and "type" and add these schema
constraint fields accordingly.

---

Nitpick comments:
In `@api-reference/openapi.json`:
- Around line 5967-5986: The OpenAPI spec repeats identical 400 and 401 response
objects for research endpoints; refactor by creating reusable entries under
components.responses (e.g., components.responses.ResearchBadRequest and
components.responses.Unauthorized or similar) that reference the existing
ResearchErrorResponse schema and then replace each inline "400" and "401"
response block with $ref pointers to those new components; update any operation
objects that currently embed the repeated blocks to use these component refs to
remove duplication and keep semantics identical.
- Around line 14965-14968: The response schema currently defines "status" as an
unconstrained string with only an example; update each affected success-response
schema (e.g., the schema object that contains the "status" property shown in
this diff and the other listed occurrences) to constrain it to the literal
"success" by replacing the loose string type with either "enum": ["success"] or
"const": "success" so the OpenAPI contract and generated SDK types reflect the
fixed success value. Locate the "status" property definitions in the shown
schema and the other occurrences (lines referenced in the comment) and change
their definition accordingly, keeping any existing example if desired.

In `@cli.mdx`:
- Around line 379-381: The heading "Deep web research" and the following
sentence repeat the same phrase; remove the redundancy by shortening the
sentence under the "Deep web research" heading to a concise descriptor (e.g.,
"Synthesizes information from across the web into a cited report.") so the
heading remains and the body becomes a single scannable line; update the
sentence text beneath the "Deep web research" heading to the concise version and
remove the original repetitive sentence.
- Line 350: Update the documentation string "List tracked radio stations" to
explicitly indicate scope by changing it to "List globally tracked radio
stations" wherever the exact phrase appears (e.g., the title or description in
the CLI docs entry that currently reads "List tracked radio stations") so the
command description is self-documenting and unambiguous; ensure the modified
phrase is used consistently in the CLI help/MDX entry and keep formatting
identical to surrounding lines.
🪄 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: 024fa5e7-386e-4e99-b43c-df41274ab422

📥 Commits

Reviewing files that changed from the base of the PR and between 8cd0bf2 and 57a4652.

📒 Files selected for processing (2)
  • api-reference/openapi.json
  • cli.mdx

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
api-reference/openapi.json (2)

5967-5986: Consider centralizing repeated 400/401 response objects under components.responses.

You already centralized the schema; centralizing the full response objects too would reduce duplication and future drift across ~30 endpoints.

♻️ Suggested DRY refactor
   "components": {
+    "responses": {
+      "ResearchValidationError": {
+        "description": "Validation error",
+        "content": {
+          "application/json": {
+            "schema": {
+              "$ref": "#/components/schemas/ResearchErrorResponse"
+            }
+          }
+        }
+      },
+      "ResearchUnauthorizedError": {
+        "description": "Authentication failed — invalid or missing API key",
+        "content": {
+          "application/json": {
+            "schema": {
+              "$ref": "#/components/schemas/ResearchErrorResponse"
+            }
+          }
+        }
+      }
+    },
     "schemas": {
       ...
-          "400": {
-            "description": "Validation error (e.g., missing required query parameter `q`)",
-            "content": {
-              "application/json": {
-                "schema": {
-                  "$ref": "#/components/schemas/ResearchErrorResponse"
-                }
-              }
-            }
-          },
-          "401": {
-            "description": "Authentication failed — invalid or missing API key",
-            "content": {
-              "application/json": {
-                "schema": {
-                  "$ref": "#/components/schemas/ResearchErrorResponse"
-                }
-              }
-            }
-          }
+          "400": { "$ref": "#/components/responses/ResearchValidationError" },
+          "401": { "$ref": "#/components/responses/ResearchUnauthorizedError" }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 5967 - 5986, Multiple endpoints
repeat identical 400 and 401 response objects; create centralized response
components (e.g., components.responses.BadRequest and
components.responses.Unauthorized that reference
components.schemas.ResearchErrorResponse) and replace the inline response
objects in the paths with $ref pointers (for example change the inline "400" and
"401" response objects to "$ref": "#/components/responses/BadRequest" and
"$ref": "#/components/responses/Unauthorized"). Update any occurrences across
the spec so all ~30 endpoints reference these new components instead of
duplicating the same content.

14976-14979: Consider re-adding explicit success enums for status on 200-response schemas.

For several updated schemas, status is now type: string with only an example. Using enum: ["success"] (and optionally marking status as required) gives stricter SDK typing and validation.

Also applies to: 15269-15272, 15542-15544, 16153-16156

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@api-reference/openapi.json` around lines 14976 - 14979, The response schemas
that currently define "status" only as type: string with an example should be
updated to a stricter definition: replace the loose "status": { "type":
"string", "example": "success" } with "status": { "type": "string", "enum":
["success"] } and add "status" to the schema's required array so SDKs
validate/tighten typing; apply this change to the shown schema and the other
instances referenced (the blocks around the other occurrences noted in the
comment).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@api-reference/openapi.json`:
- Around line 5967-5986: Multiple endpoints repeat identical 400 and 401
response objects; create centralized response components (e.g.,
components.responses.BadRequest and components.responses.Unauthorized that
reference components.schemas.ResearchErrorResponse) and replace the inline
response objects in the paths with $ref pointers (for example change the inline
"400" and "401" response objects to "$ref": "#/components/responses/BadRequest"
and "$ref": "#/components/responses/Unauthorized"). Update any occurrences
across the spec so all ~30 endpoints reference these new components instead of
duplicating the same content.
- Around line 14976-14979: The response schemas that currently define "status"
only as type: string with an example should be updated to a stricter definition:
replace the loose "status": { "type": "string", "example": "success" } with
"status": { "type": "string", "enum": ["success"] } and add "status" to the
schema's required array so SDKs validate/tighten typing; apply this change to
the shown schema and the other instances referenced (the blocks around the other
occurrences noted in the comment).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b420148f-6417-42ac-9483-25f201c52e5b

📥 Commits

Reviewing files that changed from the base of the PR and between 57a4652 and 7a6ef83.

📒 Files selected for processing (1)
  • api-reference/openapi.json

@sidneyswift
Copy link
Copy Markdown
Contributor Author

Final Verification — All Schemas Match Live API

Tested all 30 endpoints on preview deployment and compared actual response keys against the OpenAPI schemas in this PR.

# Schema Expected Keys API Match
1 ResearchSearchResponse results, status
2 ResearchAlbumsResponse albums, status
3 ResearchAudienceResponse audience_genders, top_countries, ...
4 ResearchCareerResponse career, status
5 ResearchChartsResponse data, status
6 ResearchCitiesResponse cities, status
7 ResearchCuratorResponse name, id, image_url, ...
8 ResearchDeepResponse content, citations, status
9 ResearchDiscoverResponse artists, status
10 ResearchEnrichResponse output, citations, status
11 ResearchExtractResponse results, status (errors optional)
12 ResearchFestivalsResponse festivals, status
13 ResearchGenresResponse genres, status
14 ResearchInsightsResponse insights, status
15 ResearchInstagramPostsResponse top_posts, top_reels, status
16 ResearchLookupResponse data, status
17 ResearchMetricsResponse followers, listeners, ...
18 ResearchMilestonesResponse milestones, status
19 ResearchPeopleResponse results, status
20 ResearchPlaylistResponse name, id, followers, ...
21 ResearchPlaylistsResponse placements, status
22 ResearchProfileResponse name, id, image_url, ...
23 ResearchRadioResponse stations, status
24 ResearchRankResponse rank, status
25 ResearchSimilarResponse artists, total, status
26 ResearchTrackResponse name, id, isrc, ...
27 ResearchTracksResponse tracks, status
28 ResearchUrlsResponse urls, status
29 ResearchVenuesResponse venues, status
30 ResearchWebResponse results, formatted, status

30/30 schemas match live API responses. All 30 have 200 + 400 + 401 response definitions.

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