openapi: 3.1.0 info: title: 'VerseDB API Documentation' description: 'REST API for accessing comic book data, managing collections, and building integrations with VerseDB.' version: 1.0.0 license: name: 'VerseDB API Terms of Service' url: 'https://versedb.com/policy/terms' servers: - url: 'https://versedb.com' tags: - name: Discovery description: "\nDynamic content discovery endpoints for the home screen and new releases.\n\nThese endpoints provide curated and time-sensitive content like upcoming releases,\nFOC (Final Order Cutoff) deadlines, and new first issues." - name: Titles description: "\nEndpoints for browsing comic book titles (franchises/properties).\n\nA title represents a franchise (e.g., \"Batman\"), which may have multiple series under it." - name: Series description: "\nEndpoints for browsing and searching comic book series.\n\nA series represents a specific volume or run of a title (e.g., \"Amazing Spider-Man (2018)\")." - name: Issues description: "\nEndpoints for browsing and searching comic book issues.\n\nAn issue is a single publication in a series (e.g., \"Amazing Spider-Man #1\")." - name: Publishers description: "\nEndpoints for browsing comic book publishers." - name: Imprints description: "\nEndpoints for browsing comic book imprints (publisher sub-brands, e.g.,\nVertigo under DC, Icon under Marvel)." - name: Creators description: "\nEndpoints for browsing and searching comic book creators.\n\nCreators include writers, artists, colorists, letterers, editors, and other roles." - name: Characters description: "\nEndpoints for browsing and searching comic book characters.\n\nCharacters include heroes, villains, and supporting characters across all publishers." - name: Teams description: "\nEndpoints for browsing superhero teams and their members." - name: 'Story Arcs' description: "\nEndpoints for browsing story arcs and crossover events." - name: Universes description: "\nEndpoints for browsing comic book universes (e.g., Marvel Universe, DC New 52)." - name: Events description: "\nEndpoints for browsing comic conventions and store events." - name: 'Key Issue Reasons' description: "\nEndpoints for browsing key issue reasons (e.g., \"1st Appearance\", \"Death\", \"Origin\").\nThese are reusable labels that can be attached to issues to indicate significance." - name: 'Comic Shops' description: "\nEndpoints for finding and browsing comic book shops." - name: Podcasts description: "\nEndpoints for browsing comic book podcasts and episodes." - name: Lists description: "\nUser-generated and curated lists of comic content.\n\nLists allow users to organize and share collections of issues, series, characters, creators, teams, or story arcs.\nUsers can save and like lists, and lists can be ranked or unranked.\n\n**Entity Types:** issues, series, characters, creators, story_arcs, teams\n\n**List Types:**\n- `custom` - User-created lists\n- `system` - Platform-curated lists (no owner)\n- `wishlist` - User's default wishlist (cannot be deleted)" - name: 'Barcode Lookup' description: "\nEndpoints for looking up comics by barcode (UPC or ISBN).\nUsed by the mobile app's barcode scanning feature and exposed\nto User API tokens via the `lookup:barcode` ability.\n\nOn the Mobile API the GET lookups take optional auth — tokenless requests\nare served as guests (the iOS App Clip and the signed-out app). On the\npublic User API they require the `lookup:barcode` token ability." - name: User description: "\nEndpoints for managing the authenticated user's pull list, follows, and reading progress.\n\nAll endpoints in this group require authentication with a Bearer API token." components: securitySchemes: default: type: http scheme: bearer description: 'You can retrieve your token by visiting your dashboard and clicking Generate API token. The token should be prefixed with "Bearer ".' x-speakeasy-name-override: token schemas: UnauthorizedError: type: object properties: message: type: string examples: - Unauthenticated. required: - message TooManyRequestsError: type: object properties: message: type: string examples: - 'Too Many Attempts.' required: - message security: - default: [] paths: /api/v1/discovery/foc: get: summary: 'FOC deadlines.' operationId: fOCDeadlines description: "Returns issues with Final Order Cutoff (FOC) deadline within the next N days.\nFOC is when retailers must place final orders with distributors (typically 2 weeks before release)." parameters: - in: query name: limit description: 'Max results (1-50).' required: false schema: type: integer description: 'Max results (1-50).' examples: - 10 - in: query name: days description: 'FOC window in days (1-30).' required: false schema: type: integer description: 'FOC window in days (1-30).' examples: - 7 - in: query name: start_date description: 'Start of FOC window (YYYY-MM-DD). Defaults to today.' required: false schema: type: string description: 'Start of FOC window (YYYY-MM-DD). Defaults to today.' examples: - '2026-03-15' responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 5432 number: type: string examples: - '1' title: type: string examples: - 'Amazing Spider-Man' cover_url: type: string examples: - ... release_date: type: string examples: - '2024-02-01' foc_date: type: string examples: - '2024-01-18' series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' examples: - - id: 5432 number: '1' title: 'Amazing Spider-Man' cover_url: ... release_date: '2024-02-01' foc_date: '2024-01-18' series: id: 123 name: 'Amazing Spider-Man' meta: type: object properties: foc_window_days: type: integer examples: - 7 foc_start: type: string examples: - '2024-01-15' foc_end: type: string examples: - '2024-01-22' note: type: string examples: - 'FOC dates are estimates based on release_date - 14 days' examples: - data: - id: 5432 number: '1' title: 'Amazing Spider-Man' cover_url: ... release_date: '2024-02-01' foc_date: '2024-01-18' series: id: 123 name: 'Amazing Spider-Man' meta: foc_window_days: 7 foc_start: '2024-01-15' foc_end: '2024-01-22' note: 'FOC dates are estimates based on release_date - 14 days' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Discovery /api/v1/discovery/upcoming-firsts: get: summary: 'Upcoming #1 issues.' operationId: upcoming1Issues description: "Returns upcoming first issues (#1) from new ongoing series within the next N days.\nUseful for discovering new series launches." parameters: - in: query name: limit description: 'Max results (1-50).' required: false schema: type: integer description: 'Max results (1-50).' examples: - 10 - in: query name: days description: 'Lookahead window in days (1-90).' required: false schema: type: integer description: 'Lookahead window in days (1-90).' examples: - 60 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 9876 number: type: string examples: - '1' title: type: string examples: - 'New Series #1' cover_url: type: string examples: - ... release_date: type: string examples: - '2024-02-15' series: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'New Series' status: type: string examples: - ongoing publication_type: type: string examples: - regular examples: - - id: 9876 number: '1' title: 'New Series #1' cover_url: ... release_date: '2024-02-15' series: id: 456 name: 'New Series' status: ongoing publication_type: regular meta: type: object properties: lookahead_days: type: integer examples: - 60 window_start: type: string examples: - '2024-01-15' window_end: type: string examples: - '2024-03-15' examples: - data: - id: 9876 number: '1' title: 'New Series #1' cover_url: ... release_date: '2024-02-15' series: id: 456 name: 'New Series' status: ongoing publication_type: regular meta: lookahead_days: 60 window_start: '2024-01-15' window_end: '2024-03-15' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Discovery /api/v1/discovery/follow-updates: get: summary: 'Follow updates.' operationId: followUpdates description: "Returns recent releases from the titles, characters, creators, and teams the user\nfollows. A Series is not followable — it reaches this feed through its Title, and\nevery volume of that title counts.\n\n`follow_contexts` and `follow_types` are top-level maps keyed by issue id: the\ncontext explains why the issue is shown (\"New in X-Men\"), the type is one of\n`title`, `character`, `creator`, `team`." parameters: - in: query name: days description: 'Lookback window in days (1-90).' required: false schema: type: integer description: 'Lookback window in days (1-90).' examples: - 30 - in: query name: page description: 'Page number for pagination.' required: false schema: type: integer description: 'Page number for pagination.' examples: - 1 - in: query name: per_page description: 'Items per page (1-50).' required: false schema: type: integer description: 'Items per page (1-50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 5432 issue_number: type: string examples: - '26' cover_url: type: string examples: - ... release_date: type: string examples: - '2026-03-04' series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - X-Men start_year: type: integer examples: - 2024 examples: - - id: 5432 issue_number: '26' cover_url: ... release_date: '2026-03-04' series: id: 123 name: X-Men start_year: 2024 follow_contexts: type: object properties: 5432: type: string examples: - 'New in X-Men' follow_types: type: object properties: 5432: type: string examples: - title meta: type: object properties: days: type: integer examples: - 30 total_follows: type: integer examples: - 12 current_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 1 last_page: type: integer examples: - 1 examples: - data: - id: 5432 issue_number: '26' cover_url: ... release_date: '2026-03-04' series: id: 123 name: X-Men start_year: 2024 follow_contexts: '5432': 'New in X-Men' follow_types: '5432': title meta: days: 30 total_follows: 12 current_page: 1 per_page: 20 total: 1 last_page: 1 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Discovery /api/v1/titles: get: summary: 'List titles' operationId: listTitles description: "Returns: id, name, slug, start_year, end_year, status, type, image_url,\ncontent_rating_label, min_age, is_nsfw, series_count, issues_count,\naverage_rating, total_reviews" parameters: - in: query name: q description: 'Search by title name.' required: false schema: type: string description: 'Search by title name.' examples: - spider-man - in: query name: publisher_id description: 'Filter by publisher ID.' required: false schema: type: integer description: 'Filter by publisher ID.' examples: - 1 - in: query name: publisher description: 'Deprecated alias for publisher_id, kept for existing callers.' required: false schema: type: integer description: 'Deprecated alias for publisher_id, kept for existing callers.' examples: - 1 - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 12 name: type: string examples: - Batman slug: type: string examples: - batman start_year: type: integer examples: - 1939 end_year: type: - string - 'null' examples: - null status: type: string examples: - ongoing type: type: string examples: - Series image_url: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' images: type: object properties: cover_sm: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_sm.webp' cover_md: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' cover_lg: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_lg.webp' average_rating: type: number examples: - 4.3 series_count: type: integer examples: - 25 issues_count: type: integer examples: - 1450 content_rating_label: type: string examples: - 15+ min_age: type: integer examples: - 15 is_nsfw: type: boolean examples: - false examples: - - id: 12 name: Batman slug: batman start_year: 1939 end_year: null status: ongoing type: Series image_url: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' images: cover_sm: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_sm.webp' cover_md: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' cover_lg: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_lg.webp' average_rating: 4.3 series_count: 25 issues_count: 1450 content_rating_label: 15+ min_age: 15 is_nsfw: false meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 50 per_page: type: integer examples: - 20 total: type: integer examples: - 1000 examples: - data: - id: 12 name: Batman slug: batman start_year: 1939 end_year: null status: ongoing type: Series image_url: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' images: cover_sm: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_sm.webp' cover_md: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' cover_lg: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_lg.webp' average_rating: 4.3 series_count: 25 issues_count: 1450 content_rating_label: 15+ min_age: 15 is_nsfw: false meta: current_page: 1 last_page: 50 per_page: 20 total: 1000 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Titles '/api/v1/titles/{title_id}': get: summary: 'Get a specific title' operationId: getASpecificTitle description: "Returns: id, name, slug, description, start_year, end_year, status, type,\nimage_url, content_rating_label, min_age, is_nsfw, imprint_id, series_count,\nissues_count, average_rating, total_reviews, aliases\n\nUse relationship endpoints for richer data:\n- /titles/{id}/series - Get series in a title\n- /titles/{id}/issues - Get issues across all series in a title\n- /titles/{id}/creators - Get creators credited on the title\n- /titles/{id}/characters - Get characters associated with the title\n- /titles/{id}/teams - Get teams associated with the title" parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 12 name: type: string examples: - Batman slug: type: string examples: - batman description: type: string examples: - 'The continuing adventures of the Dark Knight across his many series.' start_year: type: integer examples: - 1939 end_year: type: - string - 'null' examples: - null status: type: string examples: - ongoing type: type: string examples: - Series image_url: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' images: type: object properties: cover_sm: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_sm.webp' cover_md: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' cover_lg: type: string examples: - 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_lg.webp' content_rating_label: type: string examples: - 15+ min_age: type: integer examples: - 15 is_nsfw: type: boolean examples: - false imprint_id: type: - string - 'null' examples: - null series_count: type: integer examples: - 25 issues_count: type: integer examples: - 1450 average_rating: type: number examples: - 4.3 aliases: type: array items: type: string examples: - - 'The Dark Knight' - 'The Caped Crusader' examples: - data: id: 12 name: Batman slug: batman description: 'The continuing adventures of the Dark Knight across his many series.' start_year: 1939 end_year: null status: ongoing type: Series image_url: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' images: cover_sm: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_sm.webp' cover_md: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_md.webp' cover_lg: 'https://r2.versedb.com/uploads/titles/batman-12/batman-12-abc123-cover_lg.webp' content_rating_label: 15+ min_age: 15 is_nsfw: false imprint_id: null series_count: 25 issues_count: 1450 average_rating: 4.3 aliases: - 'The Dark Knight' - 'The Caped Crusader' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'No query results for model [App\Models\Title].' examples: - message: 'No query results for model [App\Models\Title].' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Titles parameters: - in: path name: title_id description: 'The ID of the title.' required: true schema: type: integer examples: - 147957 /api/v1/series: get: summary: 'List series.' operationId: listSeries description: 'Returns paginated series with optional search and filtering.' parameters: - in: query name: q description: 'Search by series name.' required: false schema: type: string description: 'Search by series name.' examples: - spider-man - in: query name: title_id description: 'Filter by title ID.' required: false schema: type: integer description: 'Filter by title ID.' examples: - 1 - in: query name: publisher_id description: 'Filter by publisher ID.' required: false schema: type: integer description: 'Filter by publisher ID.' examples: - 1 - in: query name: status description: 'Filter by series status (Ongoing, Completed, Canceled).' required: false schema: type: string description: 'Filter by series status (Ongoing, Completed, Canceled).' examples: - Ongoing - in: query name: sort description: 'Sort field (name, start_year, average_rating, latest_release_date, cached_issues_count).' required: false schema: type: string description: 'Sort field (name, start_year, average_rating, latest_release_date, cached_issues_count).' examples: - start_year - in: query name: direction description: 'Sort direction (asc, desc).' required: false schema: type: string description: 'Sort direction (asc, desc).' examples: - desc - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 123 title_id: type: integer examples: - 45 name: type: string examples: - 'Amazing Spider-Man' slug: type: string examples: - amazing-spider-man-2018 number: type: integer examples: - 6 start_year: type: integer examples: - 2018 end_year: type: integer examples: - 2022 cover_url: type: string examples: - 'https://...' publication_type: type: string examples: - ongoing format: type: string examples: - comic status: type: string examples: - ended original_language: type: string examples: - en cached_issues_count: type: integer examples: - 75 average_rating: type: number examples: - 4.2 total_reviews: type: integer examples: - 150 content_rating_label: type: string examples: - 15+ min_age: type: integer examples: - 15 is_nsfw: type: boolean examples: - false examples: - - id: 123 title_id: 45 name: 'Amazing Spider-Man' slug: amazing-spider-man-2018 number: 6 start_year: 2018 end_year: 2022 cover_url: 'https://...' publication_type: ongoing format: comic status: ended original_language: en cached_issues_count: 75 average_rating: 4.2 total_reviews: 150 content_rating_label: 15+ min_age: 15 is_nsfw: false meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 5 per_page: type: integer examples: - 20 total: type: integer examples: - 100 examples: - data: - id: 123 title_id: 45 name: 'Amazing Spider-Man' slug: amazing-spider-man-2018 number: 6 start_year: 2018 end_year: 2022 cover_url: 'https://...' publication_type: ongoing format: comic status: ended original_language: en cached_issues_count: 75 average_rating: 4.2 total_reviews: 150 content_rating_label: 15+ min_age: 15 is_nsfw: false meta: current_page: 1 last_page: 5 per_page: 20 total: 100 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Series '/api/v1/series/{series_id}': get: summary: 'Get series details.' operationId: getSeriesDetails description: "Returns a single series with full details including related title, publishers, and genres.\nFor relationship data (issues, creators, characters), use the relationship endpoints." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 123 title_id: type: integer examples: - 45 name: type: string examples: - 'Amazing Spider-Man' slug: type: string examples: - amazing-spider-man-2018 number: type: integer examples: - 6 start_year: type: integer examples: - 2018 end_year: type: integer examples: - 2022 cover_url: type: string examples: - 'https://...' description: type: string examples: - 'The sixth volume of Amazing Spider-Man...' publication_type: type: string examples: - ongoing format: type: string examples: - comic status: type: string examples: - ended original_language: type: string examples: - en cached_issues_count: type: integer examples: - 75 average_rating: type: number examples: - 4.2 total_reviews: type: integer examples: - 150 content_rating_label: type: string examples: - 15+ min_age: type: integer examples: - 15 is_nsfw: type: boolean examples: - false cached_creators_count: type: integer examples: - 12 cached_characters_count: type: integer examples: - 24 cached_teams_count: type: integer examples: - 3 lists_count: type: integer examples: - 8 title: type: object properties: id: type: integer examples: - 45 name: type: string examples: - 'Amazing Spider-Man' url_slug: type: string examples: - amazing-spider-man publisher: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Marvel slug: type: string examples: - marvel publishers: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Marvel slug: type: string examples: - marvel examples: - - id: 1 name: Marvel slug: marvel genres: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Superhero examples: - - id: 1 name: Superhero imprint: type: - string - 'null' examples: - null effective_imprint: type: - string - 'null' examples: - null last_edited_by: type: object properties: id: type: integer examples: - 42 name: type: string examples: - 'Jane Doe' username: type: string examples: - janedoe avatar_url: type: string examples: - 'https://...' creators: type: array items: type: object properties: id: type: integer examples: - 789 name: type: string examples: - 'Nick Spencer' slug: type: string examples: - nick-spencer photo_url: type: string examples: - 'https://...' role: type: string examples: - Writer is_uncredited: type: boolean examples: - false examples: - - id: 789 name: 'Nick Spencer' slug: nick-spencer photo_url: 'https://...' role: Writer is_uncredited: false characters: type: array items: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Spider-Man (Peter Parker)' slug: type: string examples: - spider-man-peter-parker real_name: type: string examples: - 'Peter Parker' aliases: type: array examples: - [] image_url: type: string examples: - 'https://...' appearances_count: type: integer examples: - 75 examples: - - id: 456 name: 'Spider-Man (Peter Parker)' slug: spider-man-peter-parker real_name: 'Peter Parker' aliases: [] image_url: 'https://...' appearances_count: 75 teams: type: array items: type: object properties: id: type: integer examples: - 33 name: type: string examples: - Avengers slug: type: string examples: - avengers image_url: type: string examples: - 'https://...' members_count: type: integer examples: - 24 examples: - - id: 33 name: Avengers slug: avengers image_url: 'https://...' members_count: 24 foc_issues: type: array items: type: object properties: id: type: integer examples: - 9912 issue_number: type: string examples: - '42' name: type: string examples: - 'Issue 42' release_date: type: string examples: - '2026-06-04' foc_date: type: string examples: - '2026-05-12' cover_url: type: string examples: - 'https://...' examples: - - id: 9912 issue_number: '42' name: 'Issue 42' release_date: '2026-06-04' foc_date: '2026-05-12' cover_url: 'https://...' upcoming_issues: type: array items: type: object properties: id: type: integer examples: - 9913 issue_number: type: string examples: - '43' name: type: string examples: - 'Issue 43' release_date: type: string examples: - '2026-06-11' cover_url: type: string examples: - 'https://...' examples: - - id: 9913 issue_number: '43' name: 'Issue 43' release_date: '2026-06-11' cover_url: 'https://...' examples: - data: id: 123 title_id: 45 name: 'Amazing Spider-Man' slug: amazing-spider-man-2018 number: 6 start_year: 2018 end_year: 2022 cover_url: 'https://...' description: 'The sixth volume of Amazing Spider-Man...' publication_type: ongoing format: comic status: ended original_language: en cached_issues_count: 75 average_rating: 4.2 total_reviews: 150 content_rating_label: 15+ min_age: 15 is_nsfw: false cached_creators_count: 12 cached_characters_count: 24 cached_teams_count: 3 lists_count: 8 title: id: 45 name: 'Amazing Spider-Man' url_slug: amazing-spider-man publisher: id: 1 name: Marvel slug: marvel publishers: - id: 1 name: Marvel slug: marvel genres: - id: 1 name: Superhero imprint: null effective_imprint: null last_edited_by: id: 42 name: 'Jane Doe' username: janedoe avatar_url: 'https://...' creators: - id: 789 name: 'Nick Spencer' slug: nick-spencer photo_url: 'https://...' role: Writer is_uncredited: false characters: - id: 456 name: 'Spider-Man (Peter Parker)' slug: spider-man-peter-parker real_name: 'Peter Parker' aliases: [] image_url: 'https://...' appearances_count: 75 teams: - id: 33 name: Avengers slug: avengers image_url: 'https://...' members_count: 24 foc_issues: - id: 9912 issue_number: '42' name: 'Issue 42' release_date: '2026-06-04' foc_date: '2026-05-12' cover_url: 'https://...' upcoming_issues: - id: 9913 issue_number: '43' name: 'Issue 43' release_date: '2026-06-11' cover_url: 'https://...' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Not Found' examples: - message: 'Not Found' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Series parameters: - in: path name: series_id description: 'The series ID.' required: true schema: type: integer examples: - 123 '/api/v1/series/{id}/issues': get: summary: 'Get series issues.' operationId: getSeriesIssues description: 'Returns paginated issues for a specific series.' parameters: - in: query name: q description: "Search within this series' issues (number, name)." required: false schema: type: string description: "Search within this series' issues (number, name)." examples: - '247' - in: query name: sort description: 'Sort field (issue_number, release_date, name).' required: false schema: type: string description: 'Sort field (issue_number, release_date, name).' examples: - issue_number - in: query name: direction description: 'Sort direction (asc, desc).' required: false schema: type: string description: 'Sort direction (asc, desc).' examples: - asc - in: query name: limit description: 'Results per page (max 100).' required: false schema: type: integer description: 'Results per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 5432 number: type: string examples: - '1' name: type: string examples: - 'The Amazing Spider-Man #1' release_date: type: string examples: - '2018-07-11' cover_url: type: string examples: - 'https://...' average_rating: type: number examples: - 4.5 examples: - - id: 5432 number: '1' name: 'The Amazing Spider-Man #1' release_date: '2018-07-11' cover_url: 'https://...' average_rating: 4.5 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 4 per_page: type: integer examples: - 20 total: type: integer examples: - 75 examples: - data: - id: 5432 number: '1' name: 'The Amazing Spider-Man #1' release_date: '2018-07-11' cover_url: 'https://...' average_rating: 4.5 meta: current_page: 1 last_page: 4 per_page: 20 total: 75 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Series parameters: - in: path name: id description: 'The series ID.' required: true schema: type: integer examples: - 123 '/api/v1/series/{id}/creators': get: summary: 'Get series creators.' operationId: getSeriesCreators description: 'Returns paginated creators associated with a specific series.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 789 name: type: string examples: - 'Nick Spencer' role: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Writer examples: - - id: 789 name: 'Nick Spencer' role: id: 1 name: Writer meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 50 total: type: integer examples: - 15 examples: - data: - id: 789 name: 'Nick Spencer' role: id: 1 name: Writer meta: current_page: 1 last_page: 1 per_page: 50 total: 15 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Series parameters: - in: path name: id description: 'The series ID.' required: true schema: type: integer examples: - 123 '/api/v1/series/{id}/characters': get: summary: 'Get series characters.' operationId: getSeriesCharacters description: 'Returns paginated characters appearing in a specific series.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Spider-Man (Peter Parker)' alias: type: string examples: - 'Peter Parker' image_url: type: string examples: - 'https://...' examples: - - id: 456 name: 'Spider-Man (Peter Parker)' alias: 'Peter Parker' image_url: 'https://...' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 2 per_page: type: integer examples: - 50 total: type: integer examples: - 75 examples: - data: - id: 456 name: 'Spider-Man (Peter Parker)' alias: 'Peter Parker' image_url: 'https://...' meta: current_page: 1 last_page: 2 per_page: 50 total: 75 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Series parameters: - in: path name: id description: 'The series ID.' required: true schema: type: integer examples: - 123 /api/v1/issues: get: summary: 'List issues.' operationId: listIssues description: 'Returns paginated issues with optional search, filtering, and sorting.' parameters: - in: query name: q description: 'Search by issue name.' required: false schema: type: string description: 'Search by issue name.' examples: - origin - in: query name: series_id description: 'Filter by series ID.' required: false schema: type: integer description: 'Filter by series ID.' examples: - 123 - in: query name: publisher_id description: 'Filter by publisher ID (via series relationship).' required: false schema: type: integer description: 'Filter by publisher ID (via series relationship).' examples: - 1 - in: query name: release_date_from description: 'Filter by release date (from).' required: false schema: type: string description: 'Filter by release date (from).' examples: - '2024-01-01' - in: query name: release_date_to description: 'Filter by release date (to).' required: false schema: type: string description: 'Filter by release date (to).' examples: - '2024-12-31' - in: query name: include description: 'Comma-separated relationships to include (series).' required: false schema: type: string description: 'Comma-separated relationships to include (series).' examples: - series - in: query name: sort description: 'Sort field (issue_number, release_date, name).' required: false schema: type: string description: 'Sort field (issue_number, release_date, name).' examples: - release_date - in: query name: direction description: 'Sort direction (asc, desc).' required: false schema: type: string description: 'Sort direction (asc, desc).' examples: - desc - in: query name: limit description: 'Results per page (max 100).' required: false schema: type: integer description: 'Results per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 5432 slug: type: string examples: - amazing-spider-man-1 series_id: type: integer examples: - 123 issue_number: type: string examples: - '1' name: type: string examples: - 'The Amazing Spider-Man #1' release_date: type: string examples: - '2018-07-11' cover_url: type: string examples: - 'https://...' is_reprint: type: boolean examples: - false content_rating_label: type: string examples: - 15+ min_age: type: integer examples: - 15 is_nsfw: type: boolean examples: - false examples: - - id: 5432 slug: amazing-spider-man-1 series_id: 123 issue_number: '1' name: 'The Amazing Spider-Man #1' release_date: '2018-07-11' cover_url: 'https://...' is_reprint: false content_rating_label: 15+ min_age: 15 is_nsfw: false meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 10 per_page: type: integer examples: - 20 total: type: integer examples: - 200 examples: - data: - id: 5432 slug: amazing-spider-man-1 series_id: 123 issue_number: '1' name: 'The Amazing Spider-Man #1' release_date: '2018-07-11' cover_url: 'https://...' is_reprint: false content_rating_label: 15+ min_age: 15 is_nsfw: false meta: current_page: 1 last_page: 10 per_page: 20 total: 200 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Issues '/api/v1/issues/{issue_id}': get: summary: 'Get issue details.' operationId: getIssueDetails description: "Returns a single issue with full details including series, title, publishers,\ncreators, characters, teams, and story arcs." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 5432 slug: type: string examples: - amazing-spider-man-1 series_id: type: integer examples: - 123 issue_number: type: string examples: - '1' name: type: string examples: - 'The Amazing Spider-Man #1' description: type: string examples: - 'Nick Spencer and Ryan Ottley begin a new era...' release_date: type: string examples: - '2018-07-11' cover_date: type: string examples: - '2018-09-01' cover_url: type: string examples: - 'https://...' is_reprint: type: boolean examples: - false content_rating_label: type: string examples: - 15+ min_age: type: integer examples: - 15 is_nsfw: type: boolean examples: - false page_count: type: integer examples: - 40 price: type: string examples: - '4.99' upc: type: string examples: - '75960608936700111' series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' slug: type: string examples: - amazing-spider-man-2018 title: type: object properties: id: type: integer examples: - 45 name: type: string examples: - 'Amazing Spider-Man' publisher: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Marvel slug: type: string examples: - marvel creators: type: array items: type: object properties: id: type: integer examples: - 789 name: type: string examples: - 'Nick Spencer' slug: type: string examples: - nick-spencer role: type: string examples: - Writer examples: - - id: 789 name: 'Nick Spencer' slug: nick-spencer role: Writer characters: type: array items: type: object properties: id: type: integer examples: - 456 name: type: string examples: - Spider-Man slug: type: string examples: - spider-man examples: - - id: 456 name: Spider-Man slug: spider-man examples: - data: id: 5432 slug: amazing-spider-man-1 series_id: 123 issue_number: '1' name: 'The Amazing Spider-Man #1' description: 'Nick Spencer and Ryan Ottley begin a new era...' release_date: '2018-07-11' cover_date: '2018-09-01' cover_url: 'https://...' is_reprint: false content_rating_label: 15+ min_age: 15 is_nsfw: false page_count: 40 price: '4.99' upc: '75960608936700111' series: id: 123 name: 'Amazing Spider-Man' slug: amazing-spider-man-2018 title: id: 45 name: 'Amazing Spider-Man' publisher: id: 1 name: Marvel slug: marvel creators: - id: 789 name: 'Nick Spencer' slug: nick-spencer role: Writer characters: - id: 456 name: Spider-Man slug: spider-man headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Not Found' examples: - message: 'Not Found' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Issues parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 '/api/v1/issues/{issue_id}/variants': get: summary: 'Get issue variants.' operationId: getIssueVariants description: 'Returns all variant covers for a specific issue.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 9001 variant_name: type: string examples: - 'J. Scott Campbell Variant' variant_type: type: string examples: - incentive ratio: type: string examples: - '1:25' cover_url: type: string examples: - 'https://...' creators: type: array items: type: object properties: id: type: integer examples: - 101 name: type: string examples: - 'J. Scott Campbell' role: type: string examples: - 'Cover Artist' examples: - - id: 101 name: 'J. Scott Campbell' role: 'Cover Artist' examples: - - id: 9001 variant_name: 'J. Scott Campbell Variant' variant_type: incentive ratio: '1:25' cover_url: 'https://...' creators: - id: 101 name: 'J. Scott Campbell' role: 'Cover Artist' examples: - data: - id: 9001 variant_name: 'J. Scott Campbell Variant' variant_type: incentive ratio: '1:25' cover_url: 'https://...' creators: - id: 101 name: 'J. Scott Campbell' role: 'Cover Artist' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Issues parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 '/api/v1/issues/{issue_id}/variants/{variant_id}': get: summary: 'Get variant details.' operationId: getVariantDetails description: 'Returns a specific variant cover with full details.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 9001 issue_id: type: integer examples: - 5432 variant_name: type: string examples: - 'J. Scott Campbell Variant' variant_type: type: string examples: - incentive ratio: type: string examples: - '1:25' cover_url: type: string examples: - 'https://...' price: type: string examples: - '49.99' ean: type: string examples: - '75960608936700121' creators: type: array items: type: object properties: id: type: integer examples: - 101 name: type: string examples: - 'J. Scott Campbell' slug: type: string examples: - j-scott-campbell role: type: string examples: - 'Cover Artist' examples: - - id: 101 name: 'J. Scott Campbell' slug: j-scott-campbell role: 'Cover Artist' examples: - data: id: 9001 issue_id: 5432 variant_name: 'J. Scott Campbell Variant' variant_type: incentive ratio: '1:25' cover_url: 'https://...' price: '49.99' ean: '75960608936700121' creators: - id: 101 name: 'J. Scott Campbell' slug: j-scott-campbell role: 'Cover Artist' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: error: type: string examples: - 'Variant does not belong to this issue' examples: - error: 'Variant does not belong to this issue' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Issues parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 - in: path name: variant_id description: 'The variant ID.' required: true schema: type: integer examples: - 9001 '/api/v1/issues/{id}/creators': get: summary: 'Get issue creators.' operationId: getIssueCreators description: 'Returns paginated creators for a specific issue with their roles.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 789 name: type: string examples: - 'Nick Spencer' role: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Writer examples: - - id: 789 name: 'Nick Spencer' role: id: 1 name: Writer - id: 790 name: 'Ryan Ottley' role: id: 2 name: Artist meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 50 total: type: integer examples: - 8 examples: - data: - id: 789 name: 'Nick Spencer' role: id: 1 name: Writer - id: 790 name: 'Ryan Ottley' role: id: 2 name: Artist meta: current_page: 1 last_page: 1 per_page: 50 total: 8 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Issues parameters: - in: path name: id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 '/api/v1/issues/{id}/characters': get: summary: 'Get issue characters.' operationId: getIssueCharacters description: 'Returns paginated characters appearing in a specific issue.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Spider-Man (Peter Parker)' alias: type: string examples: - 'Peter Parker' image_url: type: string examples: - 'https://...' examples: - - id: 456 name: 'Spider-Man (Peter Parker)' alias: 'Peter Parker' image_url: 'https://...' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 50 total: type: integer examples: - 15 examples: - data: - id: 456 name: 'Spider-Man (Peter Parker)' alias: 'Peter Parker' image_url: 'https://...' meta: current_page: 1 last_page: 1 per_page: 50 total: 15 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Issues parameters: - in: path name: id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 '/api/v1/issues/{issue_id}/key-reasons': get: summary: 'Get key issue reasons.' operationId: getKeyIssueReasons description: 'Returns key issue reasons for a specific issue (e.g., "1st Appearance", "Death").' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - '1st Appearance' category: type: string examples: - appearance description: type: string examples: - 'First appearance of a character' notes: type: string examples: - '1st full appearance of Wolverine (Logan)' source: type: string examples: - manual examples: - - id: 1 name: '1st Appearance' category: appearance description: 'First appearance of a character' notes: '1st full appearance of Wolverine (Logan)' source: manual examples: - data: - id: 1 name: '1st Appearance' category: appearance description: 'First appearance of a character' notes: '1st full appearance of Wolverine (Logan)' source: manual headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Issues parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 /api/v1/publishers: get: summary: 'List all publishers with optional search' operationId: listAllPublishersWithOptionalSearch description: 'Returns: id, name, founded_year, headquarters, status, logo_url' parameters: - in: query name: q description: 'Search by publisher name.' required: false schema: type: string description: 'Search by publisher name.' examples: - marvel - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - 'Marvel Comics' founded_year: type: integer examples: - 1939 headquarters: type: string examples: - 'New York, NY' status: type: string examples: - active series_count: type: integer examples: - 12500 logo_url: type: string examples: - 'https://...-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://...-tile_sm.webp' profile_md: type: string examples: - 'https://...-profile_md.webp' full_lg: type: string examples: - 'https://...-full_lg.webp' examples: - - id: 1 name: 'Marvel Comics' founded_year: 1939 headquarters: 'New York, NY' status: active series_count: 12500 logo_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 25 per_page: type: integer examples: - 20 total: type: integer examples: - 500 examples: - data: - id: 1 name: 'Marvel Comics' founded_year: 1939 headquarters: 'New York, NY' status: active series_count: 12500 logo_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' meta: current_page: 1 last_page: 25 per_page: 20 total: 500 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Publishers '/api/v1/publishers/{publisher_id}': get: summary: 'Get publisher details' operationId: getPublisherDetails description: "Returns: id, name, description, founded_year, first_published_year,\nwebsite, headquarters, parent_company, status, logo_url, aliases\n\nUse the related endpoints for relationship data:\n- /series?publisher_id={id} - Get series by publisher\n- /publishers/{id}/characters - Get characters by publisher" parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 1 name: type: string examples: - 'Marvel Comics' description: type: string examples: - 'American comic book publisher, home to Spider-Man, the X-Men, and the Avengers.' founded_year: type: integer examples: - 1939 website: type: string examples: - 'https://www.marvel.com' headquarters: type: string examples: - 'New York, NY' parent_company: type: string examples: - 'The Walt Disney Company' status: type: string examples: - active logo_url: type: string examples: - 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-tile_sm.webp' profile_md: type: string examples: - 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-profile_md.webp' full_lg: type: string examples: - 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-full_lg.webp' first_published_year: type: integer examples: - 1939 aliases: type: array items: type: string examples: - - Marvel - 'Timely Comics' - 'Atlas Comics' examples: - data: id: 1 name: 'Marvel Comics' description: 'American comic book publisher, home to Spider-Man, the X-Men, and the Avengers.' founded_year: 1939 website: 'https://www.marvel.com' headquarters: 'New York, NY' parent_company: 'The Walt Disney Company' status: active logo_url: 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-full_lg.webp' images: tile_sm: 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-tile_sm.webp' profile_md: 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-profile_md.webp' full_lg: 'https://r2.versedb.com/uploads/publishers/marvel-1/marvel-1-full_lg.webp' first_published_year: 1939 aliases: - Marvel - 'Timely Comics' - 'Atlas Comics' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'No query results for model [App\Models\Publisher].' examples: - message: 'No query results for model [App\Models\Publisher].' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Publishers parameters: - in: path name: publisher_id description: 'The ID of the publisher.' required: true schema: type: integer examples: - 6 /api/v1/imprints: get: summary: 'List imprints' operationId: listImprints description: 'Returns: id, name, slug, description, publisher' parameters: - in: query name: q description: 'Search by imprint name.' required: false schema: type: string description: 'Search by imprint name.' examples: - vertigo - in: query name: publisher_id description: 'Filter by publisher ID.' required: false schema: type: integer description: 'Filter by publisher ID.' examples: - 2 - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 7 name: type: string examples: - Vertigo slug: type: string examples: - vertigo description: type: string examples: - "DC's mature readers imprint, home to Sandman, Preacher, and Y: The Last Man." publisher: type: object properties: id: type: integer examples: - 2 name: type: string examples: - 'DC Comics' slug: type: string examples: - dc-comics examples: - - id: 7 name: Vertigo slug: vertigo description: "DC's mature readers imprint, home to Sandman, Preacher, and Y: The Last Man." publisher: id: 2 name: 'DC Comics' slug: dc-comics meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 3 per_page: type: integer examples: - 20 total: type: integer examples: - 45 examples: - data: - id: 7 name: Vertigo slug: vertigo description: "DC's mature readers imprint, home to Sandman, Preacher, and Y: The Last Man." publisher: id: 2 name: 'DC Comics' slug: dc-comics meta: current_page: 1 last_page: 3 per_page: 20 total: 45 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Imprints '/api/v1/imprints/{imprint_id}': get: summary: 'Get imprint details' operationId: getImprintDetails description: 'Returns: id, name, slug, description, publisher, series_count, titles_count' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 7 name: type: string examples: - Vertigo slug: type: string examples: - vertigo description: type: string examples: - "DC's mature readers imprint, home to Sandman, Preacher, and Y: The Last Man." publisher: type: object properties: id: type: integer examples: - 2 name: type: string examples: - 'DC Comics' slug: type: string examples: - dc-comics series_count: type: integer examples: - 312 titles_count: type: integer examples: - 145 created_at: type: string examples: - '2024-01-15T12:00:00.000000Z' updated_at: type: string examples: - '2024-06-01T08:30:00.000000Z' examples: - data: id: 7 name: Vertigo slug: vertigo description: "DC's mature readers imprint, home to Sandman, Preacher, and Y: The Last Man." publisher: id: 2 name: 'DC Comics' slug: dc-comics series_count: 312 titles_count: 145 created_at: '2024-01-15T12:00:00.000000Z' updated_at: '2024-06-01T08:30:00.000000Z' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Imprints parameters: - in: path name: imprint_id description: 'The ID of the imprint.' required: true schema: type: integer examples: - 6 /api/v1/creators: get: summary: 'List creators.' operationId: listCreators description: 'Returns paginated creators with optional search and sorting.' parameters: - in: query name: q description: 'Search by creator name.' required: false schema: type: string description: 'Search by creator name.' examples: - 'alan moore' - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 789 name: type: string examples: - 'Alan Moore' slug: type: string examples: - alan-moore role: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Writer roles: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Writer examples: - - id: 1 name: Writer - id: 2 name: Artist photo_url: type: string examples: - 'https://...-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://...-tile_sm.webp' profile_md: type: string examples: - 'https://...-profile_md.webp' full_lg: type: string examples: - 'https://...-full_lg.webp' examples: - - id: 789 name: 'Alan Moore' slug: alan-moore role: id: 1 name: Writer roles: - id: 1 name: Writer - id: 2 name: Artist photo_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 100 per_page: type: integer examples: - 20 total: type: integer examples: - 2000 examples: - data: - id: 789 name: 'Alan Moore' slug: alan-moore role: id: 1 name: Writer roles: - id: 1 name: Writer - id: 2 name: Artist photo_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' meta: current_page: 1 last_page: 100 per_page: 20 total: 2000 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Creators '/api/v1/creators/{creator_id}': get: summary: 'Get creator details.' operationId: getCreatorDetails description: 'Returns a single creator with full details including biography, role, and awards.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 789 name: type: string examples: - 'Alan Moore' slug: type: string examples: - alan-moore role: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Writer roles: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Writer examples: - - id: 1 name: Writer - id: 2 name: Artist photo_url: type: string examples: - 'https://...-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://...-tile_sm.webp' profile_md: type: string examples: - 'https://...-profile_md.webp' full_lg: type: string examples: - 'https://...-full_lg.webp' biography: type: string examples: - 'Alan Moore is a British comic book writer...' gender: type: string examples: - male birth: type: string examples: - '1953-11-18' death: type: - string - 'null' examples: - null birth_place: type: string examples: - 'Northampton, England' country: type: string examples: - 'United Kingdom' aliases: type: array examples: - [] links: type: object properties: website: type: string examples: - ... twitter: type: string examples: - ... awards: type: array items: type: object properties: name: type: string examples: - 'Eisner Award' year: type: integer examples: - 1988 examples: - - name: 'Eisner Award' year: 1988 examples: - data: id: 789 name: 'Alan Moore' slug: alan-moore role: id: 1 name: Writer roles: - id: 1 name: Writer - id: 2 name: Artist photo_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' biography: 'Alan Moore is a British comic book writer...' gender: male birth: '1953-11-18' death: null birth_place: 'Northampton, England' country: 'United Kingdom' aliases: [] links: website: ... twitter: ... awards: - name: 'Eisner Award' year: 1988 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Not Found' examples: - message: 'Not Found' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Creators parameters: - in: path name: creator_id description: 'The creator ID.' required: true schema: type: integer examples: - 789 '/api/v1/creators/{creator_id}/blog-posts': get: summary: "Get creator's blog posts." operationId: getCreatorsBlogPosts description: 'Returns paginated published blog posts where this creator is featured.' parameters: - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 10 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 12 slug: type: string examples: - spotlight-alan-moore title: type: string examples: - 'Creator Spotlight: Alan Moore' featured_image_url: type: string examples: - 'https://...' category: type: object properties: id: type: integer examples: - 2 name: type: string examples: - Spotlights slug: type: string examples: - spotlights author: type: object properties: id: type: integer examples: - 1 name: type: string examples: - 'VerseDB Editorial' published_at: type: string examples: - '2026-04-15T12:00:00+00:00' reading_time: type: integer examples: - 6 examples: - - id: 12 slug: spotlight-alan-moore title: 'Creator Spotlight: Alan Moore' featured_image_url: 'https://...' category: id: 2 name: Spotlights slug: spotlights author: id: 1 name: 'VerseDB Editorial' published_at: '2026-04-15T12:00:00+00:00' reading_time: 6 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 10 total: type: integer examples: - 3 examples: - data: - id: 12 slug: spotlight-alan-moore title: 'Creator Spotlight: Alan Moore' featured_image_url: 'https://...' category: id: 2 name: Spotlights slug: spotlights author: id: 1 name: 'VerseDB Editorial' published_at: '2026-04-15T12:00:00+00:00' reading_time: 6 meta: current_page: 1 last_page: 1 per_page: 10 total: 3 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Creators parameters: - in: path name: creator_id description: 'The creator ID.' required: true schema: type: integer examples: - 789 '/api/v1/creators/{creator_id}/issues': get: summary: "Get creator's issues." operationId: getCreatorsIssues description: 'Returns paginated issues where the creator has a credit.' parameters: - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 20 - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: medium description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' required: false schema: type: string description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' examples: - 'comic,manga' responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 123 slug: type: string examples: - batman-1 series_id: type: integer examples: - 456 issue_number: type: string examples: - '1' name: type: string examples: - 'Batman #1' release_date: type: string examples: - '2023-01-15' cover_url: type: string examples: - 'https://...' series: type: object properties: id: type: integer examples: - 456 name: type: string examples: - Batman slug: type: string examples: - batman examples: - - id: 123 slug: batman-1 series_id: 456 issue_number: '1' name: 'Batman #1' release_date: '2023-01-15' cover_url: 'https://...' series: id: 456 name: Batman slug: batman meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 10 per_page: type: integer examples: - 20 total: type: integer examples: - 200 examples: - data: - id: 123 slug: batman-1 series_id: 456 issue_number: '1' name: 'Batman #1' release_date: '2023-01-15' cover_url: 'https://...' series: id: 456 name: Batman slug: batman meta: current_page: 1 last_page: 10 per_page: 20 total: 200 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Creators parameters: - in: path name: creator_id description: 'The creator ID.' required: true schema: type: integer examples: - 789 '/api/v1/creators/{creator_id}/series': get: summary: "Get creator's series." operationId: getCreatorsSeries description: 'Returns paginated series where the creator has worked.' parameters: - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 20 - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: medium description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' required: false schema: type: string description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' examples: - 'comic,manga' responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 456 name: type: string examples: - Batman slug: type: string examples: - batman start_year: type: integer examples: - 2016 end_year: type: integer examples: - 2020 cover_url: type: string examples: - 'https://...' cached_issues_count: type: integer examples: - 85 examples: - - id: 456 name: Batman slug: batman start_year: 2016 end_year: 2020 cover_url: 'https://...' cached_issues_count: 85 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 5 per_page: type: integer examples: - 20 total: type: integer examples: - 100 examples: - data: - id: 456 name: Batman slug: batman start_year: 2016 end_year: 2020 cover_url: 'https://...' cached_issues_count: 85 meta: current_page: 1 last_page: 5 per_page: 20 total: 100 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Creators parameters: - in: path name: creator_id description: 'The creator ID.' required: true schema: type: integer examples: - 789 /api/v1/characters: get: summary: 'List characters.' operationId: listCharacters description: 'Returns paginated characters with optional search and sorting.' parameters: - in: query name: q description: 'Search by character name.' required: false schema: type: string description: 'Search by character name.' examples: - spider-man - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Spider-Man (Peter Parker)' slug: type: string examples: - spider-man-peter-parker real_name: type: string examples: - 'Peter Parker' aliases: type: array items: type: string examples: - - Spidey - Web-Head image_url: type: string examples: - 'https://...-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://...-tile_sm.webp' profile_md: type: string examples: - 'https://...-profile_md.webp' full_lg: type: string examples: - 'https://...-full_lg.webp' examples: - - id: 456 name: 'Spider-Man (Peter Parker)' slug: spider-man-peter-parker real_name: 'Peter Parker' aliases: - Spidey - Web-Head image_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 50 per_page: type: integer examples: - 20 total: type: integer examples: - 1000 examples: - data: - id: 456 name: 'Spider-Man (Peter Parker)' slug: spider-man-peter-parker real_name: 'Peter Parker' aliases: - Spidey - Web-Head image_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' meta: current_page: 1 last_page: 50 per_page: 20 total: 1000 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Characters '/api/v1/characters/{character_id}': get: summary: 'Get character details.' operationId: getCharacterDetails description: "Returns a single character with full details including publishers and\ncached relationship counts (appearances, series, teams, story arcs) so\nclients can decide which related-entity tabs to expose." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Spider-Man (Peter Parker)' slug: type: string examples: - spider-man-peter-parker real_name: type: string examples: - 'Peter Parker' aliases: type: array items: type: string examples: - - Spidey - Web-Head - Webslinger image_url: type: string examples: - 'https://...-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://...-tile_sm.webp' profile_md: type: string examples: - 'https://...-profile_md.webp' full_lg: type: string examples: - 'https://...-full_lg.webp' description: type: string examples: - 'Peter Parker was bitten by a radioactive spider...' alter_ego: type: array examples: - [] gender: type: string examples: - male race: type: string examples: - Human birth_place: type: string examples: - 'Queens, New York' occupation: type: string examples: - 'Photographer, Scientist' appearances_count: type: integer examples: - 12500 series_count: type: integer examples: - 320 teams_count: type: integer examples: - 8 story_arcs_count: type: integer examples: - 47 powers: type: array items: type: string examples: - - 'Super strength' - Wall-crawling - Spider-sense publisher: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Marvel slug: type: string examples: - marvel examples: - data: id: 456 name: 'Spider-Man (Peter Parker)' slug: spider-man-peter-parker real_name: 'Peter Parker' aliases: - Spidey - Web-Head - Webslinger image_url: 'https://...-full_lg.webp' images: tile_sm: 'https://...-tile_sm.webp' profile_md: 'https://...-profile_md.webp' full_lg: 'https://...-full_lg.webp' description: 'Peter Parker was bitten by a radioactive spider...' alter_ego: [] gender: male race: Human birth_place: 'Queens, New York' occupation: 'Photographer, Scientist' appearances_count: 12500 series_count: 320 teams_count: 8 story_arcs_count: 47 powers: - 'Super strength' - Wall-crawling - Spider-sense publisher: id: 1 name: Marvel slug: marvel headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Not Found' examples: - message: 'Not Found' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Characters parameters: - in: path name: character_id description: 'The character ID.' required: true schema: type: integer examples: - 456 '/api/v1/characters/{character_id}/series': get: summary: 'Get character series.' operationId: getCharacterSeries description: 'Returns paginated series where the character appears.' parameters: - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 20 - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: medium description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' required: false schema: type: string description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' examples: - 'comic,manga' responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' slug: type: string examples: - amazing-spider-man-2018 start_year: type: integer examples: - 2018 end_year: type: integer examples: - 2022 image_url: type: string examples: - 'https://...' examples: - - id: 123 name: 'Amazing Spider-Man' slug: amazing-spider-man-2018 start_year: 2018 end_year: 2022 image_url: 'https://...' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 5 per_page: type: integer examples: - 20 total: type: integer examples: - 100 examples: - data: - id: 123 name: 'Amazing Spider-Man' slug: amazing-spider-man-2018 start_year: 2018 end_year: 2022 image_url: 'https://...' meta: current_page: 1 last_page: 5 per_page: 20 total: 100 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Characters parameters: - in: path name: character_id description: 'The character ID.' required: true schema: type: integer examples: - 456 '/api/v1/characters/{character_id}/issues': get: summary: 'Get character issues.' operationId: getCharacterIssues description: 'Returns paginated issues where the character appears, ordered by release date.' parameters: - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 20 - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: medium description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' required: false schema: type: string description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' examples: - 'comic,manga' responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 5432 number: type: string examples: - '1' name: type: string examples: - 'The Amazing Spider-Man #1' release_date: type: string examples: - '2018-07-11' cover_url: type: string examples: - 'https://...' series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' examples: - - id: 5432 number: '1' name: 'The Amazing Spider-Man #1' release_date: '2018-07-11' cover_url: 'https://...' series: id: 123 name: 'Amazing Spider-Man' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 100 per_page: type: integer examples: - 20 total: type: integer examples: - 2000 examples: - data: - id: 5432 number: '1' name: 'The Amazing Spider-Man #1' release_date: '2018-07-11' cover_url: 'https://...' series: id: 123 name: 'Amazing Spider-Man' meta: current_page: 1 last_page: 100 per_page: 20 total: 2000 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Characters parameters: - in: path name: character_id description: 'The character ID.' required: true schema: type: integer examples: - 456 '/api/v1/characters/{character_id}/teams': get: summary: 'Get character teams.' operationId: getCharacterTeams description: 'Returns paginated teams the character is a member of, including membership details.' parameters: - in: query name: limit description: 'Results per page (max 50).' required: false schema: type: integer description: 'Results per page (max 50).' examples: - 20 - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 10 name: type: string examples: - Avengers slug: type: string examples: - avengers image_url: type: string examples: - 'https://...' membership: type: object properties: role: type: string examples: - Member joined_date: type: string examples: - '2012-05-01' left_date: type: - string - 'null' examples: - null examples: - - id: 10 name: Avengers slug: avengers image_url: 'https://...' membership: role: Member joined_date: '2012-05-01' left_date: null meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 5 examples: - data: - id: 10 name: Avengers slug: avengers image_url: 'https://...' membership: role: Member joined_date: '2012-05-01' left_date: null meta: current_page: 1 last_page: 1 per_page: 20 total: 5 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Characters parameters: - in: path name: character_id description: 'The character ID.' required: true schema: type: integer examples: - 456 /api/v1/teams: get: summary: 'List all teams with optional search' operationId: listAllTeamsWithOptionalSearch description: 'Returns a paginated list of teams. Use `q` to search by team name.' parameters: - in: query name: q description: 'Search by team name.' required: false schema: type: string description: 'Search by team name.' examples: - avengers - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 12 name: type: string examples: - Avengers slug: type: string examples: - avengers aliases: type: array items: type: string examples: - - "Earth's Mightiest Heroes" headquarters: type: string examples: - 'Avengers Tower, New York City' members_count: type: integer examples: - 42 appearances_count: type: integer examples: - 1250 image_url: type: string examples: - 'https://images.versedb.com/teams/avengers/tile_sm.webp' images: type: object properties: tile_sm: type: string examples: - 'https://images.versedb.com/teams/avengers/tile_sm.webp' profile_md: type: string examples: - 'https://images.versedb.com/teams/avengers/profile_md.webp' full_lg: type: string examples: - 'https://images.versedb.com/teams/avengers/full_lg.webp' examples: - - id: 12 name: Avengers slug: avengers aliases: - "Earth's Mightiest Heroes" headquarters: 'Avengers Tower, New York City' members_count: 42 appearances_count: 1250 image_url: 'https://images.versedb.com/teams/avengers/tile_sm.webp' images: tile_sm: 'https://images.versedb.com/teams/avengers/tile_sm.webp' profile_md: 'https://images.versedb.com/teams/avengers/profile_md.webp' full_lg: 'https://images.versedb.com/teams/avengers/full_lg.webp' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 8 per_page: type: integer examples: - 20 total: type: integer examples: - 156 examples: - data: - id: 12 name: Avengers slug: avengers aliases: - "Earth's Mightiest Heroes" headquarters: 'Avengers Tower, New York City' members_count: 42 appearances_count: 1250 image_url: 'https://images.versedb.com/teams/avengers/tile_sm.webp' images: tile_sm: 'https://images.versedb.com/teams/avengers/tile_sm.webp' profile_md: 'https://images.versedb.com/teams/avengers/profile_md.webp' full_lg: 'https://images.versedb.com/teams/avengers/full_lg.webp' meta: current_page: 1 last_page: 8 per_page: 20 total: 156 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Teams '/api/v1/teams/{team_id}': get: summary: 'Get a specific team' operationId: getASpecificTeam description: "Returns team details without relationship data.\nUse the relationship endpoints for related data:\n- /teams/{id}/characters - Get team members\n- /teams/{id}/series - Get team's series appearances\n- /teams/{id}/issues - Get team's issue appearances" parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 78 name: type: string examples: - Avengers slug: type: string examples: - avengers aliases: type: array items: type: string examples: - - "Earth's Mightiest Heroes" description: type: string examples: - 'A team of superheroes formed to confront threats no single hero could withstand.' formation_date: type: string examples: - '1963-09-01' disbanded_date: type: - string - 'null' examples: - null headquarters: type: string examples: - 'Avengers Tower, New York' members_count: type: integer examples: - 312 series_count: type: integer examples: - 48 appearances_count: type: integer examples: - 5200 lists_count: type: integer examples: - 86 image_url: type: string examples: - 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-tile_sm.webp' profile_md: type: string examples: - 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-profile_md.webp' full_lg: type: string examples: - 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-full_lg.webp' examples: - data: id: 78 name: Avengers slug: avengers aliases: - "Earth's Mightiest Heroes" description: 'A team of superheroes formed to confront threats no single hero could withstand.' formation_date: '1963-09-01' disbanded_date: null headquarters: 'Avengers Tower, New York' members_count: 312 series_count: 48 appearances_count: 5200 lists_count: 86 image_url: 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-full_lg.webp' images: tile_sm: 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-tile_sm.webp' profile_md: 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-profile_md.webp' full_lg: 'https://r2.versedb.com/uploads/teams/avengers-78/avengers-78-full_lg.webp' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'No query results for model [App\Models\Team].' examples: - message: 'No query results for model [App\Models\Team].' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Teams parameters: - in: path name: team_id description: 'The ID of the team.' required: true schema: type: integer examples: - 24 '/api/v1/teams/{team_id}/characters': get: summary: 'Get characters for a specific team (members)' operationId: getCharactersForASpecificTeammembers description: "Returns the team's character roster." parameters: - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Captain America' slug: type: string examples: - captain-america real_name: type: string examples: - 'Steve Rogers' aliases: type: array items: type: string examples: - - Cap - 'Sentinel of Liberty' race: type: string examples: - Human image_url: type: string examples: - 'https://images.versedb.com/characters/captain-america/full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://images.versedb.com/characters/captain-america/tile_sm.webp' profile_md: type: string examples: - 'https://images.versedb.com/characters/captain-america/profile_md.webp' full_lg: type: string examples: - 'https://images.versedb.com/characters/captain-america/full_lg.webp' appearances_count: type: integer examples: - 980 publisher_name: type: string examples: - 'Marvel Comics' pivot_role: type: string examples: - Leader pivot_joined_date: type: string examples: - '1963-09-01' examples: - - id: 456 name: 'Captain America' slug: captain-america real_name: 'Steve Rogers' aliases: - Cap - 'Sentinel of Liberty' race: Human image_url: 'https://images.versedb.com/characters/captain-america/full_lg.webp' images: tile_sm: 'https://images.versedb.com/characters/captain-america/tile_sm.webp' profile_md: 'https://images.versedb.com/characters/captain-america/profile_md.webp' full_lg: 'https://images.versedb.com/characters/captain-america/full_lg.webp' appearances_count: 980 publisher_name: 'Marvel Comics' pivot_role: Leader pivot_joined_date: '1963-09-01' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 4 per_page: type: integer examples: - 20 total: type: integer examples: - 67 examples: - data: - id: 456 name: 'Captain America' slug: captain-america real_name: 'Steve Rogers' aliases: - Cap - 'Sentinel of Liberty' race: Human image_url: 'https://images.versedb.com/characters/captain-america/full_lg.webp' images: tile_sm: 'https://images.versedb.com/characters/captain-america/tile_sm.webp' profile_md: 'https://images.versedb.com/characters/captain-america/profile_md.webp' full_lg: 'https://images.versedb.com/characters/captain-america/full_lg.webp' appearances_count: 980 publisher_name: 'Marvel Comics' pivot_role: Leader pivot_joined_date: '1963-09-01' meta: current_page: 1 last_page: 4 per_page: 20 total: 67 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Teams parameters: - in: path name: team_id description: 'The ID of the team.' required: true schema: type: integer examples: - 24 '/api/v1/teams/{team_id}/series': get: summary: 'Get series for a specific team' operationId: getSeriesForASpecificTeam description: 'Returns the series the team appears in.' parameters: - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 - in: query name: medium description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' required: false schema: type: string description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' examples: - 'comic,manga' responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 123 title_id: type: integer examples: - 45 name: type: string examples: - Avengers slug: type: string examples: - avengers-2018 start_year: type: integer examples: - 2018 end_year: type: integer examples: - 2023 medium: type: string examples: - comic publication_type: type: string examples: - regular_series status: type: string examples: - ended average_rating: type: number examples: - 4.1 total_reviews: type: integer examples: - 150 is_nsfw: type: boolean examples: - false examples: - - id: 123 title_id: 45 name: Avengers slug: avengers-2018 start_year: 2018 end_year: 2023 medium: comic publication_type: regular_series status: ended average_rating: 4.1 total_reviews: 150 is_nsfw: false meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 12 examples: - data: - id: 123 title_id: 45 name: Avengers slug: avengers-2018 start_year: 2018 end_year: 2023 medium: comic publication_type: regular_series status: ended average_rating: 4.1 total_reviews: 150 is_nsfw: false meta: current_page: 1 last_page: 1 per_page: 20 total: 12 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Teams parameters: - in: path name: team_id description: 'The ID of the team.' required: true schema: type: integer examples: - 24 - in: path name: team description: 'The team ID.' required: true schema: type: integer examples: - 10 '/api/v1/teams/{team_id}/issues': get: summary: 'Get issues for a specific team' operationId: getIssuesForASpecificTeam description: 'Returns the issues the team appears in.' parameters: - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 - in: query name: medium description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' required: false schema: type: string description: 'Comma-separated series mediums to filter by (comic, manga, manhwa, manhua, bande_dessinee, magazine).' examples: - 'comic,manga' responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 5432 series_id: type: integer examples: - 123 issue_number: type: string examples: - '1' name: type: string examples: - 'The Final Host' release_date: type: string examples: - '2018-05-02' cover_date: type: string examples: - '2018-07-01' average_rating: type: number examples: - 4.3 is_nsfw: type: boolean examples: - false examples: - - id: 5432 series_id: 123 issue_number: '1' name: 'The Final Host' release_date: '2018-05-02' cover_date: '2018-07-01' average_rating: 4.3 is_nsfw: false meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 25 per_page: type: integer examples: - 20 total: type: integer examples: - 1250 examples: - data: - id: 5432 series_id: 123 issue_number: '1' name: 'The Final Host' release_date: '2018-05-02' cover_date: '2018-07-01' average_rating: 4.3 is_nsfw: false meta: current_page: 1 last_page: 25 per_page: 20 total: 1250 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Teams parameters: - in: path name: team_id description: 'The ID of the team.' required: true schema: type: integer examples: - 24 - in: path name: team description: 'The team ID.' required: true schema: type: integer examples: - 10 /api/v1/story-arcs: get: summary: 'List all story arcs with optional search' operationId: listAllStoryArcsWithOptionalSearch description: "Returns a paginated list of story arcs and crossover events, newest first.\nNarrow the results with `q`, `status`, or `type`." parameters: - in: query name: q description: 'Search by story arc name.' required: false schema: type: string description: 'Search by story arc name.' examples: - 'civil war' - in: query name: status description: 'Filter by status.' required: false schema: type: string description: 'Filter by status.' examples: - ended - in: query name: type description: 'Filter by type.' required: false schema: type: string description: 'Filter by type.' examples: - crossover_event - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 16 name: type: string examples: - 'Civil War' slug: type: string examples: - civil-war type: type: string examples: - crossover_event status: type: string examples: - ended image_url: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: type: object properties: cover_sm: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' issues_count: type: integer examples: - 102 primary_universe: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Earth-616 examples: - - id: 16 name: 'Civil War' slug: civil-war type: crossover_event status: ended image_url: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' issues_count: 102 primary_universe: id: 1 name: Earth-616 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 12 per_page: type: integer examples: - 20 total: type: integer examples: - 230 examples: - data: - id: 16 name: 'Civil War' slug: civil-war type: crossover_event status: ended image_url: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' issues_count: 102 primary_universe: id: 1 name: Earth-616 meta: current_page: 1 last_page: 12 per_page: 20 total: 230 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Story Arcs' '/api/v1/story-arcs/{storyArc_id}': get: summary: 'Get story arc detail.' operationId: getStoryArcDetail description: "Returns full story arc detail with the primary and secondary universes,\na denormalized characters count, the start/end issue summaries (each\nwith its parent series), and the last user who edited the arc.\n\nPaginated relationship data lives on dedicated nested endpoints:\n- GET /story-arcs/{id}/issues - Issues in the arc, in reading order\n- GET /story-arcs/{id}/series - Series spanned by the arc\n- GET /story-arcs/{id}/characters - Characters appearing in the arc" parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 16 name: type: string examples: - 'Civil War' slug: type: string examples: - civil-war description: type: string examples: - 'A superhero registration act divides the Marvel Universe...' type: type: string examples: - crossover_event status: type: string examples: - ended image_url: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: type: object properties: cover_sm: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' primary_universe_id: type: integer examples: - 1 issues_count: type: integer examples: - 102 characters_count: type: integer examples: - 87 primary_universe: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Earth-616 description: type: string examples: - 'The primary continuity of the Marvel Universe.' universes: type: array items: type: object properties: id: type: integer examples: - 12 name: type: string examples: - 'Ultimate Universe' examples: - - id: 12 name: 'Ultimate Universe' start_issue: type: object properties: id: type: integer examples: - 5432 name: type: string examples: - 'Civil War #1' slug: type: string examples: - civil-war-1 issue_number: type: string examples: - '1' series_id: type: integer examples: - 412 cover_url: type: string examples: - 'https://cdn.versedb.com/issues/civil-war-1-md.jpg' images: type: object properties: cover_md: type: string examples: - 'https://cdn.versedb.com/issues/civil-war-1-md.jpg' series: type: object properties: id: type: integer examples: - 412 name: type: string examples: - 'Civil War' slug: type: string examples: - civil-war-2006 start_year: type: integer examples: - 2006 end_issue: type: object properties: id: type: integer examples: - 5439 name: type: string examples: - 'Civil War #7' slug: type: string examples: - civil-war-7 issue_number: type: string examples: - '7' series_id: type: integer examples: - 412 cover_url: type: string examples: - 'https://cdn.versedb.com/issues/civil-war-7-md.jpg' images: type: object properties: cover_md: type: string examples: - 'https://cdn.versedb.com/issues/civil-war-7-md.jpg' series: type: object properties: id: type: integer examples: - 412 name: type: string examples: - 'Civil War' slug: type: string examples: - civil-war-2006 start_year: type: integer examples: - 2006 last_edited_by: type: object properties: id: type: integer examples: - 42 name: type: string examples: - 'Jane Doe' username: type: string examples: - janedoe avatar_url: type: string examples: - 'https://cdn.versedb.com/users/janedoe-md.jpg' examples: - data: id: 16 name: 'Civil War' slug: civil-war description: 'A superhero registration act divides the Marvel Universe...' type: crossover_event status: ended image_url: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' primary_universe_id: 1 issues_count: 102 characters_count: 87 primary_universe: id: 1 name: Earth-616 description: 'The primary continuity of the Marvel Universe.' universes: - id: 12 name: 'Ultimate Universe' start_issue: id: 5432 name: 'Civil War #1' slug: civil-war-1 issue_number: '1' series_id: 412 cover_url: 'https://cdn.versedb.com/issues/civil-war-1-md.jpg' images: cover_md: 'https://cdn.versedb.com/issues/civil-war-1-md.jpg' series: id: 412 name: 'Civil War' slug: civil-war-2006 start_year: 2006 end_issue: id: 5439 name: 'Civil War #7' slug: civil-war-7 issue_number: '7' series_id: 412 cover_url: 'https://cdn.versedb.com/issues/civil-war-7-md.jpg' images: cover_md: 'https://cdn.versedb.com/issues/civil-war-7-md.jpg' series: id: 412 name: 'Civil War' slug: civil-war-2006 start_year: 2006 last_edited_by: id: 42 name: 'Jane Doe' username: janedoe avatar_url: 'https://cdn.versedb.com/users/janedoe-md.jpg' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Story Arcs' parameters: - in: path name: storyArc_id description: 'The story arc ID.' required: true schema: type: integer examples: - 16 '/api/v1/issues/{issue_id}/story-arcs': get: summary: 'Get story arcs for a specific issue' operationId: getStoryArcsForASpecificIssue description: 'Returns every story arc the given issue is part of.' parameters: - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 24 name: type: string examples: - 'The Night Gwen Stacy Died' slug: type: string examples: - the-night-gwen-stacy-died type: type: string examples: - main_story status: type: string examples: - ended image_url: type: string examples: - 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' images: type: object properties: cover_sm: type: string examples: - 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-sm.jpg' cover_md: type: string examples: - 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' cover_lg: type: string examples: - 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-lg.jpg' issues_count: type: integer examples: - 2 examples: - - id: 24 name: 'The Night Gwen Stacy Died' slug: the-night-gwen-stacy-died type: main_story status: ended image_url: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-lg.jpg' issues_count: 2 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 1 examples: - data: - id: 24 name: 'The Night Gwen Stacy Died' slug: the-night-gwen-stacy-died type: main_story status: ended image_url: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-lg.jpg' issues_count: 2 meta: current_page: 1 last_page: 1 per_page: 20 total: 1 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Story Arcs' parameters: - in: path name: issue_id description: 'The ID of the issue.' required: true schema: type: integer examples: - 744355 '/api/v1/characters/{character_id}/story-arcs': get: summary: 'Get story arcs for a specific character' operationId: getStoryArcsForASpecificCharacter description: 'Returns every story arc the given character appears in.' parameters: - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 16 name: type: string examples: - 'Civil War' slug: type: string examples: - civil-war type: type: string examples: - crossover_event status: type: string examples: - ended image_url: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: type: object properties: cover_sm: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: type: string examples: - 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' issues_count: type: integer examples: - 102 examples: - - id: 16 name: 'Civil War' slug: civil-war type: crossover_event status: ended image_url: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' issues_count: 102 - id: 24 name: 'The Night Gwen Stacy Died' slug: the-night-gwen-stacy-died type: main_story status: ended image_url: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-lg.jpg' issues_count: 2 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 3 per_page: type: integer examples: - 20 total: type: integer examples: - 41 examples: - data: - id: 16 name: 'Civil War' slug: civil-war type: crossover_event status: ended image_url: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/civil-war-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/civil-war-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/civil-war-lg.jpg' issues_count: 102 - id: 24 name: 'The Night Gwen Stacy Died' slug: the-night-gwen-stacy-died type: main_story status: ended image_url: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/the-night-gwen-stacy-died-lg.jpg' issues_count: 2 meta: current_page: 1 last_page: 3 per_page: 20 total: 41 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Story Arcs' parameters: - in: path name: character_id description: 'The ID of the character.' required: true schema: type: integer examples: - 130195 '/api/v1/universes/{universe_id}/story-arcs': get: summary: 'Get story arcs for a specific universe' operationId: getStoryArcsForASpecificUniverse description: 'Returns every story arc that takes place in the given universe.' parameters: - in: query name: q description: 'Optional case-insensitive search within these results.' required: false schema: type: string description: 'Optional case-insensitive search within these results.' examples: - batman - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 88 name: type: string examples: - 'Crisis on Infinite Earths' slug: type: string examples: - crisis-on-infinite-earths type: type: string examples: - crossover_event status: type: string examples: - ended image_url: type: string examples: - 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-md.jpg' images: type: object properties: cover_sm: type: string examples: - 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-sm.jpg' cover_md: type: string examples: - 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-md.jpg' cover_lg: type: string examples: - 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-lg.jpg' issues_count: type: integer examples: - 12 examples: - - id: 88 name: 'Crisis on Infinite Earths' slug: crisis-on-infinite-earths type: crossover_event status: ended image_url: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-lg.jpg' issues_count: 12 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 3 per_page: type: integer examples: - 20 total: type: integer examples: - 56 examples: - data: - id: 88 name: 'Crisis on Infinite Earths' slug: crisis-on-infinite-earths type: crossover_event status: ended image_url: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-md.jpg' images: cover_sm: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-sm.jpg' cover_md: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-md.jpg' cover_lg: 'https://cdn.versedb.com/story_arcs/crisis-on-infinite-earths-lg.jpg' issues_count: 12 meta: current_page: 1 last_page: 3 per_page: 20 total: 56 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Story Arcs' parameters: - in: path name: universe_id description: 'The ID of the universe.' required: true schema: type: integer examples: - 16 /api/v1/universes: get: summary: 'List universes' operationId: listUniverses description: 'Returns: id, name' parameters: - in: query name: q description: 'Search by universe name.' required: false schema: type: string description: 'Search by universe name.' examples: - marvel - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - 'Marvel Universe (616)' examples: - - id: 1 name: 'Marvel Universe (616)' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 3 per_page: type: integer examples: - 20 total: type: integer examples: - 42 examples: - data: - id: 1 name: 'Marvel Universe (616)' meta: current_page: 1 last_page: 3 per_page: 20 total: 42 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Universes '/api/v1/universes/{universe_id}': get: summary: 'Get a specific universe' operationId: getASpecificUniverse description: "Returns: id, name, description\n\nUse the relationship endpoints for related data:\n- /universes/{id}/story-arcs - Get story arcs in a universe\n- /universes/{id}/characters - Get characters in a universe" parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 1 name: type: string examples: - 'Marvel Universe (616)' description: type: string examples: - 'The primary continuity of Marvel Comics, home to most mainline Marvel stories since 1961.' examples: - data: id: 1 name: 'Marvel Universe (616)' description: 'The primary continuity of Marvel Comics, home to most mainline Marvel stories since 1961.' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Universes parameters: - in: path name: universe_id description: 'The ID of the universe.' required: true schema: type: integer examples: - 16 /api/v1/events: get: summary: 'List events.' operationId: listEvents description: 'Returns: id, slug, name, type, dates, location info, logo_url' parameters: - in: query name: q description: 'Search by event name.' required: false schema: type: string description: 'Search by event name.' examples: - comic-con - in: query name: type description: 'Filter by type (convention, store_event, signing, etc).' required: false schema: type: string description: 'Filter by type (convention, store_event, signing, etc).' examples: - convention - in: query name: upcoming description: 'Only show upcoming events.' required: false schema: type: boolean description: 'Only show upcoming events.' examples: - true - in: query name: past description: 'Only show past events.' required: false schema: type: boolean description: 'Only show past events.' examples: - true - in: query name: is_online description: 'Filter online/in-person events.' required: false schema: type: boolean description: 'Filter online/in-person events.' examples: - false - in: query name: is_fcbd description: 'Filter Free Comic Book Day events.' required: false schema: type: boolean description: 'Filter Free Comic Book Day events.' examples: - true - in: query name: country_code description: 'Filter by country code.' required: false schema: type: string description: 'Filter by country code.' examples: - US - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 42 slug: type: string examples: - san-diego-comic-con-2026 name: type: string examples: - 'San Diego Comic-Con 2026' type: type: string examples: - convention status: type: string examples: - scheduled start_date: type: string examples: - '2026-07-23' end_date: type: string examples: - '2026-07-26' is_online: type: boolean examples: - false is_fcbd: type: boolean examples: - false venue_name: type: string examples: - 'San Diego Convention Center' city: type: string examples: - 'San Diego' region: type: string examples: - CA country_code: type: string examples: - US full_location: type: string examples: - 'San Diego Convention Center, San Diego, CA, United States' logo_url: type: string examples: - 'https://...-tile_sm.webp' images: type: object properties: tile_sm: type: string examples: - 'https://...-tile_sm.webp' full_md: type: string examples: - 'https://...-full_md.webp' full_lg: type: string examples: - 'https://...-full_lg.webp' ticket_price: type: string examples: - '$45.00 - $150.00' follower_count: type: integer examples: - 320 examples: - - id: 42 slug: san-diego-comic-con-2026 name: 'San Diego Comic-Con 2026' type: convention status: scheduled start_date: '2026-07-23' end_date: '2026-07-26' is_online: false is_fcbd: false venue_name: 'San Diego Convention Center' city: 'San Diego' region: CA country_code: US full_location: 'San Diego Convention Center, San Diego, CA, United States' logo_url: 'https://...-tile_sm.webp' images: tile_sm: 'https://...-tile_sm.webp' full_md: 'https://...-full_md.webp' full_lg: 'https://...-full_lg.webp' ticket_price: '$45.00 - $150.00' follower_count: 320 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 8 per_page: type: integer examples: - 20 total: type: integer examples: - 156 examples: - data: - id: 42 slug: san-diego-comic-con-2026 name: 'San Diego Comic-Con 2026' type: convention status: scheduled start_date: '2026-07-23' end_date: '2026-07-26' is_online: false is_fcbd: false venue_name: 'San Diego Convention Center' city: 'San Diego' region: CA country_code: US full_location: 'San Diego Convention Center, San Diego, CA, United States' logo_url: 'https://...-tile_sm.webp' images: tile_sm: 'https://...-tile_sm.webp' full_md: 'https://...-full_md.webp' full_lg: 'https://...-full_lg.webp' ticket_price: '$45.00 - $150.00' follower_count: 320 meta: current_page: 1 last_page: 8 per_page: 20 total: 156 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Events '/api/v1/events/{event_id}': get: summary: 'Get an event.' operationId: getAnEvent description: 'Returns full event details including links and map data.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 42 slug: type: string examples: - san-diego-comic-con-2026 name: type: string examples: - 'San Diego Comic-Con 2026' type: type: string examples: - convention status: type: string examples: - scheduled start_date: type: string examples: - '2026-07-23' end_date: type: string examples: - '2026-07-26' timezone: type: string examples: - America/Los_Angeles is_online: type: boolean examples: - false is_fcbd: type: boolean examples: - false venue_name: type: string examples: - 'San Diego Convention Center' street_address: type: string examples: - '111 W Harbor Dr' city: type: string examples: - 'San Diego' region: type: string examples: - CA postal_code: type: string examples: - '92101' country_code: type: string examples: - US latitude: type: number examples: - 32.7065 longitude: type: number examples: - -117.1615 full_location: type: string examples: - 'San Diego Convention Center, San Diego, CA, United States' google_maps_url: type: string examples: - 'https://maps.google.com/?q=32.7065,-117.1615' logo_url: type: string examples: - 'https://cdn.versedb.com/events/42-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://cdn.versedb.com/events/42-tile_sm.webp' full_md: type: string examples: - 'https://cdn.versedb.com/events/42-full_md.webp' full_lg: type: string examples: - 'https://cdn.versedb.com/events/42-full_lg.webp' static_map_url: type: string examples: - 'https://cdn.versedb.com/events/42-static-map.png' event_url: type: string examples: - 'https://www.comic-con.org' ticket_price_min: type: string examples: - '45.00' ticket_price_max: type: string examples: - '150.00' ticket_currency: type: string examples: - USD ticket_price: type: string examples: - '$45.00 - $150.00' follower_count: type: integer examples: - 320 creators: type: array items: type: object properties: id: type: integer examples: - 7 name: type: string examples: - 'Stan Lee' slug: type: string examples: - stan-lee photo_url: type: string examples: - 'https://cdn.versedb.com/creators/7-profile_md.webp' images: type: object properties: {} country: type: string examples: - US appearance_types: type: array items: type: string examples: - - 'Special Guest' examples: - - id: 7 name: 'Stan Lee' slug: stan-lee photo_url: 'https://cdn.versedb.com/creators/7-profile_md.webp' images: [] country: US appearance_types: - 'Special Guest' issues: type: array examples: - [] issue_variants: type: array examples: - [] attendees_preview: type: object properties: total: type: integer examples: - 320 users: type: array items: type: object properties: id: type: integer examples: - 1024 username: type: string examples: - comic_fan_42 name: type: string examples: - 'Comic Fan' profile_image_url: type: string examples: - 'https://cdn.versedb.com/users/1024-profile_sm.webp' is_private: type: boolean examples: - false examples: - - id: 1024 username: comic_fan_42 name: 'Comic Fan' profile_image_url: 'https://cdn.versedb.com/users/1024-profile_sm.webp' is_private: false - id: 1536 username: panel_pusher name: Riley profile_image_url: 'https://cdn.versedb.com/users/1536-profile_sm.webp' is_private: false related_events: type: array examples: - [] examples: - data: id: 42 slug: san-diego-comic-con-2026 name: 'San Diego Comic-Con 2026' type: convention status: scheduled start_date: '2026-07-23' end_date: '2026-07-26' timezone: America/Los_Angeles is_online: false is_fcbd: false venue_name: 'San Diego Convention Center' street_address: '111 W Harbor Dr' city: 'San Diego' region: CA postal_code: '92101' country_code: US latitude: 32.7065 longitude: -117.1615 full_location: 'San Diego Convention Center, San Diego, CA, United States' google_maps_url: 'https://maps.google.com/?q=32.7065,-117.1615' logo_url: 'https://cdn.versedb.com/events/42-full_lg.webp' images: tile_sm: 'https://cdn.versedb.com/events/42-tile_sm.webp' full_md: 'https://cdn.versedb.com/events/42-full_md.webp' full_lg: 'https://cdn.versedb.com/events/42-full_lg.webp' static_map_url: 'https://cdn.versedb.com/events/42-static-map.png' event_url: 'https://www.comic-con.org' ticket_price_min: '45.00' ticket_price_max: '150.00' ticket_currency: USD ticket_price: '$45.00 - $150.00' follower_count: 320 creators: - id: 7 name: 'Stan Lee' slug: stan-lee photo_url: 'https://cdn.versedb.com/creators/7-profile_md.webp' images: {} country: US appearance_types: - 'Special Guest' issues: [] issue_variants: [] attendees_preview: total: 320 users: - id: 1024 username: comic_fan_42 name: 'Comic Fan' profile_image_url: 'https://cdn.versedb.com/users/1024-profile_sm.webp' is_private: false - id: 1536 username: panel_pusher name: Riley profile_image_url: 'https://cdn.versedb.com/users/1536-profile_sm.webp' is_private: false related_events: [] headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found or Archived' content: application/json: schema: type: object properties: message: type: string examples: - 'Not found.' examples: - message: 'Not found.' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Events parameters: - in: path name: event_id description: 'The event ID.' required: true schema: type: integer examples: - 42 /api/v1/key-issue-reasons: get: summary: 'List key issue reasons.' operationId: listKeyIssueReasons description: "Returns active key issue reasons, optionally filtered by category or name. Reasons are written\nper issue rather than drawn from a fixed vocabulary, so there are far more of them than the\ncategory list suggests — pass `q` and `limit` for a picker rather than fetching the lot." parameters: - in: query name: category description: 'Filter by category (appearance, story, creator, market, media).' required: false schema: type: string description: 'Filter by category (appearance, story, creator, market, media).' examples: - appearance - in: query name: q description: 'Match reasons whose name contains this.' required: false schema: type: string description: 'Match reasons whose name contains this.' examples: - '1st appearance' - in: query name: limit description: 'Cap the number returned (1-100). Applied only when q is present.' required: false schema: type: integer description: 'Cap the number returned (1-100). Applied only when q is present.' examples: - 12 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 1 name: type: string examples: - '1st Appearance' category: type: string examples: - appearance description: type: string examples: - 'First appearance of a character' examples: - - id: 1 name: '1st Appearance' category: appearance description: 'First appearance of a character' examples: - data: - id: 1 name: '1st Appearance' category: appearance description: 'First appearance of a character' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Key Issue Reasons' /api/v1/shops: get: summary: 'List comic shops.' operationId: listComicShops description: 'Returns paginated shops with optional location-based and text filtering.' parameters: - in: query name: country description: 'Filter by country. Accepts an ISO alpha-2 code or canonical country name.' required: false schema: type: string description: 'Filter by country. Accepts an ISO alpha-2 code or canonical country name.' examples: - US - in: query name: state description: 'Filter by state or province.' required: false schema: type: string description: 'Filter by state or province.' examples: - NY - in: query name: city description: 'Filter by city. Accepts the city name or its URL slug, case-insensitive.' required: false schema: type: string description: 'Filter by city. Accepts the city name or its URL slug, case-insensitive.' examples: - 'New York' - in: query name: q description: 'Search by shop name or city.' required: false schema: type: string description: 'Search by shop name or city.' examples: - manhattan - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 42 name: type: string examples: - 'Midtown Comics' city: type: string examples: - 'New York' state_province: type: string examples: - NY country: type: string examples: - 'United States' logo_url: type: string examples: - 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-tile_sm.webp' images: type: object properties: tile_sm: type: string examples: - 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-tile_sm.webp' full_lg: type: string examples: - 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-full_lg.webp' examples: - - id: 42 name: 'Midtown Comics' city: 'New York' state_province: NY country: 'United States' logo_url: 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-tile_sm.webp' images: tile_sm: 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-tile_sm.webp' full_lg: 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-full_lg.webp' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 8 per_page: type: integer examples: - 20 total: type: integer examples: - 150 examples: - data: - id: 42 name: 'Midtown Comics' city: 'New York' state_province: NY country: 'United States' logo_url: 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-tile_sm.webp' images: tile_sm: 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-tile_sm.webp' full_lg: 'https://r2.versedb.com/uploads/comic-shops/midtown-comics-42/midtown-comics-42-abc123-full_lg.webp' meta: current_page: 1 last_page: 8 per_page: 20 total: 150 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Comic Shops' '/api/v1/shops/{shop_id}': get: summary: 'Get a comic shop.' operationId: getAComicShop description: "Returns full shop details including services offered.\n\n`operating_hours` is keyed Monday-first by lowercase day name. Each value is\neither `closed` or one or more 24-hour `HH:MM-HH:MM` ranges joined by commas\n(a split shift reads `09:00-13:00,15:00-19:00`). A day missing from the map\nhas unknown hours — that is not the same as the shop being closed that day." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 42 name: type: string examples: - 'Midtown Comics' description: type: string examples: - 'Flagship comic shop in the heart of Manhattan.' address: type: string examples: - '200 W 40th St' city: type: string examples: - 'New York' state_province: type: string examples: - NY postal_code: type: string examples: - '10018' country: type: string examples: - US website: type: string examples: - 'https://www.midtowncomics.com' full_address: type: string examples: - '200 W 40th St, New York, NY 10018' logo_url: type: string examples: - 'https://r2.versedb.com/uploads/shops/midtown-42/midtown-42-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://r2.versedb.com/uploads/shops/midtown-42/midtown-42-tile_sm.webp' full_lg: type: string examples: - 'https://r2.versedb.com/uploads/shops/midtown-42/midtown-42-full_lg.webp' operating_hours: type: object properties: monday: type: string examples: - '10:00-20:00' saturday: type: string examples: - '10:00-21:00' sunday: type: string examples: - closed services: type: array items: type: string examples: - - 'New Comics' - 'Back Issues' - 'Pull Lists' - Grading events: type: array examples: - [] examples: - data: id: 42 name: 'Midtown Comics' description: 'Flagship comic shop in the heart of Manhattan.' address: '200 W 40th St' city: 'New York' state_province: NY postal_code: '10018' country: US website: 'https://www.midtowncomics.com' full_address: '200 W 40th St, New York, NY 10018' logo_url: 'https://r2.versedb.com/uploads/shops/midtown-42/midtown-42-full_lg.webp' images: tile_sm: 'https://r2.versedb.com/uploads/shops/midtown-42/midtown-42-tile_sm.webp' full_lg: 'https://r2.versedb.com/uploads/shops/midtown-42/midtown-42-full_lg.webp' operating_hours: monday: '10:00-20:00' saturday: '10:00-21:00' sunday: closed services: - 'New Comics' - 'Back Issues' - 'Pull Lists' - Grading events: [] headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'No query results for model [App\Models\ComicShop].' examples: - message: 'No query results for model [App\Models\ComicShop].' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Comic Shops' parameters: - in: path name: shop_id description: 'The shop ID.' required: true schema: type: integer examples: - 1 /api/v1/podcasts: get: summary: 'List all podcasts with optional search' operationId: listAllPodcastsWithOptionalSearch description: "Returns a paginated list of comic book podcasts and YouTube channels, plus\nthe set of languages present in the catalog. Filter with `q`, `type`, or `language`." parameters: - in: query name: q description: 'Search by podcast name.' required: false schema: type: string description: 'Search by podcast name.' examples: - comic - in: query name: type description: 'Filter by type (podcast or youtube).' required: false schema: type: string description: 'Filter by type (podcast or youtube).' examples: - youtube - in: query name: language description: 'Filter by language code (e.g., en, ja, fr).' required: false schema: type: string description: 'Filter by language code (e.g., en, ja, fr).' examples: - en - in: query name: limit description: 'Number of results per page (max 50).' required: false schema: type: integer description: 'Number of results per page (max 50).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 56 name: type: string examples: - 'War Rocket Ajax' slug: type: string examples: - war-rocket-ajax type: type: string examples: - podcast description: type: string examples: - 'A weekly comic book podcast covering new releases and creator interviews.' language: type: string examples: - en logo_url: type: string examples: - 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-tile_sm.webp' full_lg: type: string examples: - 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' follower_count: type: integer examples: - 1240 subscriber_count: type: integer examples: - 8800 categories: type: array items: type: string examples: - - Comics - 'Pop Culture' examples: - - id: 56 name: 'War Rocket Ajax' slug: war-rocket-ajax type: podcast description: 'A weekly comic book podcast covering new releases and creator interviews.' language: en logo_url: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' images: tile_sm: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-tile_sm.webp' full_lg: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' follower_count: 1240 subscriber_count: 8800 categories: - Comics - 'Pop Culture' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 15 per_page: type: integer examples: - 20 total: type: integer examples: - 300 languages: type: array items: type: string examples: - - en - es - fr - ja examples: - data: - id: 56 name: 'War Rocket Ajax' slug: war-rocket-ajax type: podcast description: 'A weekly comic book podcast covering new releases and creator interviews.' language: en logo_url: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' images: tile_sm: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-tile_sm.webp' full_lg: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' follower_count: 1240 subscriber_count: 8800 categories: - Comics - 'Pop Culture' meta: current_page: 1 last_page: 15 per_page: 20 total: 300 languages: - en - es - fr - ja headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Podcasts '/api/v1/podcasts/{podcast_id}': get: summary: 'Get a specific podcast.' operationId: getASpecificPodcast description: 'Returns full detail for one podcast, including its feed, platform links, and categories.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 56 name: type: string examples: - 'War Rocket Ajax' slug: type: string examples: - war-rocket-ajax type: type: string examples: - podcast description: type: string examples: - 'A weekly comic book podcast covering new releases, industry news, and creator interviews.' language: type: string examples: - en logo_url: type: string examples: - 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' images: type: object properties: tile_sm: type: string examples: - 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-tile_sm.webp' full_lg: type: string examples: - 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' website_url: type: string examples: - 'https://warrocketajax.com' rss_feed_url: type: string examples: - 'https://feeds.example.com/war-rocket-ajax' youtube_channel_id: type: - string - 'null' examples: - null social_links: type: object properties: website: type: string examples: - 'https://warrocketajax.com' twitter: type: string examples: - 'https://twitter.com/warrocketajax' platform_links: type: object properties: apple: type: string examples: - 'https://podcasts.apple.com/us/podcast/id123456' spotify: type: string examples: - 'https://open.spotify.com/show/abc123' follower_count: type: integer examples: - 1240 subscriber_count: type: integer examples: - 8800 categories: type: array items: type: string examples: - - Comics - 'Pop Culture' examples: - data: id: 56 name: 'War Rocket Ajax' slug: war-rocket-ajax type: podcast description: 'A weekly comic book podcast covering new releases, industry news, and creator interviews.' language: en logo_url: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' images: tile_sm: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-tile_sm.webp' full_lg: 'https://r2.versedb.com/uploads/podcasts/wra-56/wra-56-full_lg.webp' website_url: 'https://warrocketajax.com' rss_feed_url: 'https://feeds.example.com/war-rocket-ajax' youtube_channel_id: null social_links: website: 'https://warrocketajax.com' twitter: 'https://twitter.com/warrocketajax' platform_links: apple: 'https://podcasts.apple.com/us/podcast/id123456' spotify: 'https://open.spotify.com/show/abc123' follower_count: 1240 subscriber_count: 8800 categories: - Comics - 'Pop Culture' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'No query results for model [App\Models\Podcast].' examples: - message: 'No query results for model [App\Models\Podcast].' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Podcasts parameters: - in: path name: podcast_id description: 'The ID of the podcast.' required: true schema: type: integer examples: - 86 /api/v1/lists: get: summary: 'Browse lists.' operationId: browseLists description: "Returns paginated public lists with filtering and sorting options.\nOnly shows lists with at least one item." parameters: - in: query name: q description: 'Search by list title or description.' required: false schema: type: string description: 'Search by list title or description.' examples: - spider-man - in: query name: entity_type description: 'Filter by entity type (issues, series, characters, creators, story_arcs, teams). Matches lists declared as that type plus unrestricted lists holding at least one item of it.' required: false schema: type: string description: 'Filter by entity type (issues, series, characters, creators, story_arcs, teams). Matches lists declared as that type plus unrestricted lists holding at least one item of it.' examples: - issues - in: query name: type description: 'Filter by who made it — `curated` for staff lists, `community` for everyone else. Omit for both.' required: false schema: type: string description: 'Filter by who made it — `curated` for staff lists, `community` for everyone else. Omit for both.' examples: - curated - in: query name: sort description: 'Sort order (featured, newest, popular, most_saved). Default: featured.' required: false schema: type: string description: 'Sort order (featured, newest, popular, most_saved). Default: featured.' examples: - popular - in: query name: limit description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 101 title: type: string examples: - 'Best Spider-Man Stories' entity_type: type: string examples: - issues is_ranked: type: boolean examples: - true items_count: type: integer examples: - 25 likes_count: type: integer examples: - 150 saves_count: type: integer examples: - 89 user: type: object properties: id: type: integer examples: - 123 username: type: string examples: - comic_fan avatar: type: string examples: - 'https://...' preview_items: type: array items: type: object properties: id: type: integer examples: - 1 image_url: type: string examples: - 'https://...' is_nsfw: type: boolean examples: - false examples: - - id: 1 image_url: 'https://...' is_nsfw: false examples: - - id: 101 title: 'Best Spider-Man Stories' entity_type: issues is_ranked: true items_count: 25 likes_count: 150 saves_count: 89 user: id: 123 username: comic_fan avatar: 'https://...' preview_items: - id: 1 image_url: 'https://...' is_nsfw: false meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 5 per_page: type: integer examples: - 20 total: type: integer examples: - 100 examples: - data: - id: 101 title: 'Best Spider-Man Stories' entity_type: issues is_ranked: true items_count: 25 likes_count: 150 saves_count: 89 user: id: 123 username: comic_fan avatar: 'https://...' preview_items: - id: 1 image_url: 'https://...' is_nsfw: false meta: current_page: 1 last_page: 5 per_page: 20 total: 100 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists post: summary: 'Create list.' operationId: createList description: 'Creates a new user list.' parameters: [] responses: '201': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 102 title: type: string examples: - 'Best Spider-Man Stories' description: type: string examples: - 'My favorite Spidey moments ranked' entity_type: type: string examples: - issues is_ranked: type: boolean examples: - true is_private: type: boolean examples: - false items_count: type: integer examples: - 0 user: type: object properties: id: type: integer examples: - 123 username: type: string examples: - comic_fan examples: - data: id: 102 title: 'Best Spider-Man Stories' description: 'My favorite Spidey moments ranked' entity_type: issues is_ranked: true is_private: false items_count: 0 user: id: 123 username: comic_fan headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Limit Reached' content: application/json: schema: type: object properties: message: type: string examples: - 'You have reached the maximum number of lists. Upgrade to PRO for more.' examples: - message: 'You have reached the maximum number of lists. Upgrade to PRO for more.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists requestBody: required: true content: application/json: schema: type: object properties: title: type: string description: 'List title (max 100 chars).' examples: - 'Best Spider-Man Stories' description: type: - string - 'null' description: 'List description (max 2000 chars).' examples: - 'My favorite Spidey moments ranked' entity_type: type: - string - 'null' description: 'The kind of item a smart-list rule matches (issues, series, characters, creators, story_arcs, teams). Required, and never `mixed`, when `rules` is supplied; ignored without it, because a list you fill by hand holds any combination of types.' examples: - issues is_ranked: type: boolean description: 'Whether items are ranked/ordered. Defaults to true.' examples: - true is_private: type: boolean description: 'Whether the list is private. Requires a Pro subscription. Defaults to false.' examples: - false rules: type: - object - 'null' description: 'A smart-list rule. Supply it to have the list built and kept current from a query instead of by hand. Requires a Pro subscription, and forces `is_ranked` to false because the rule carries its own sort. Fetch the field catalog from `/lists/rule-vocabulary` and validate a draft against `/lists/rule-preview`.' properties: {} examples: - version: 2 match: all: - field: launch_date op: within_last value: count: 3 unit: months sort: field: launch_date direction: desc limit: 500 required: - title /api/v1/lists/system: get: summary: 'Browse system lists.' operationId: browseSystemLists description: 'Returns platform-curated lists (no user owner). These are editorial picks and featured content.' parameters: - in: query name: entity_type description: 'Filter by entity type (issues, series, characters, creators, story_arcs, teams).' required: false schema: type: string description: 'Filter by entity type (issues, series, characters, creators, story_arcs, teams).' examples: - issues - in: query name: sort description: 'Sort order (newest, popular).' required: false schema: type: string description: 'Sort order (newest, popular).' examples: - popular - in: query name: limit description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 1 title: type: string examples: - 'Essential Batman Reading Order' entity_type: type: string examples: - issues is_ranked: type: boolean examples: - true items_count: type: integer examples: - 50 likes_count: type: integer examples: - 500 user: type: - string - 'null' examples: - null preview_items: type: array items: type: object properties: id: type: integer examples: - 1 image_url: type: string examples: - 'https://...' is_nsfw: type: boolean examples: - false examples: - - id: 1 image_url: 'https://...' is_nsfw: false examples: - - id: 1 title: 'Essential Batman Reading Order' entity_type: issues is_ranked: true items_count: 50 likes_count: 500 user: null preview_items: - id: 1 image_url: 'https://...' is_nsfw: false meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 2 per_page: type: integer examples: - 20 total: type: integer examples: - 30 examples: - data: - id: 1 title: 'Essential Batman Reading Order' entity_type: issues is_ranked: true items_count: 50 likes_count: 500 user: null preview_items: - id: 1 image_url: 'https://...' is_nsfw: false meta: current_page: 1 last_page: 2 per_page: 20 total: 30 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists '/api/v1/lists/{list_id}': get: summary: 'Get list.' operationId: getList description: 'Returns a single list with all its items. Private lists are only visible to owners.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 101 title: type: string examples: - 'Best Spider-Man Stories' description: type: string examples: - 'My favorite Spidey moments' entity_type: type: string examples: - issues is_ranked: type: boolean examples: - true is_private: type: boolean examples: - false items_count: type: integer examples: - 25 likes_count: type: integer examples: - 150 saves_count: type: integer examples: - 89 user: type: object properties: id: type: integer examples: - 123 username: type: string examples: - comic_fan name: type: string examples: - John items: type: array items: type: object properties: id: type: integer examples: - 1 position: type: integer examples: - 1 note: type: string examples: - Classic! created_at: type: string examples: - '2024-01-15T10:30:00Z' updated_at: type: string examples: - '2024-01-15T10:30:00Z' variant_id: type: integer examples: - 7 variant: type: object properties: id: type: integer examples: - 7 name: type: string examples: - 'Virgin Variant' cover_image_url: type: string examples: - 'https://cdn.versedb.com/variants/7/cover_md.webp' entity_type: type: string examples: - issues entity: type: object properties: id: type: integer examples: - 5432 slug: type: string examples: - the-amazing-spider-man-1 name: type: string examples: - 'The Amazing Spider-Man #1' issue_number: type: string examples: - '1' release_date: type: string examples: - '2018-07-11' image_url: type: string examples: - 'https://cdn.versedb.com/issues/5432/cover_md.webp' is_nsfw: type: boolean examples: - false publisher: type: string examples: - 'Marvel Comics' series: type: object properties: id: type: integer examples: [88] name: type: string examples: ['The Amazing Spider-Man'] slug: type: string examples: [the-amazing-spider-man] start_year: type: integer examples: [2018] examples: - - id: 1 position: 1 note: Classic! created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' variant_id: 7 variant: id: 7 name: 'Virgin Variant' cover_image_url: 'https://cdn.versedb.com/variants/7/cover_md.webp' entity_type: issues entity: id: 5432 slug: the-amazing-spider-man-1 name: 'The Amazing Spider-Man #1' issue_number: '1' release_date: '2018-07-11' image_url: 'https://cdn.versedb.com/issues/5432/cover_md.webp' is_nsfw: false publisher: 'Marvel Comics' series: id: 88 name: 'The Amazing Spider-Man' slug: the-amazing-spider-man start_year: 2018 - id: 2 position: 2 note: null created_at: '2024-01-15T10:31:00Z' updated_at: '2024-01-15T10:31:00Z' variant_id: null entity_type: issues entity: id: 5433 slug: the-amazing-spider-man-2 name: 'The Amazing Spider-Man #2' issue_number: '2' release_date: '2018-07-25' image_url: 'https://cdn.versedb.com/issues/5433/cover_md.webp' is_nsfw: false publisher: 'Marvel Comics' series: id: 88 name: 'The Amazing Spider-Man' slug: the-amazing-spider-man start_year: 2018 created_at: type: string examples: - '2024-01-15T10:30:00Z' examples: - data: id: 101 title: 'Best Spider-Man Stories' description: 'My favorite Spidey moments' entity_type: issues is_ranked: true is_private: false items_count: 25 likes_count: 150 saves_count: 89 user: id: 123 username: comic_fan name: John items: - id: 1 position: 1 note: Classic! created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' variant_id: 7 variant: id: 7 name: 'Virgin Variant' cover_image_url: 'https://cdn.versedb.com/variants/7/cover_md.webp' entity_type: issues entity: id: 5432 slug: the-amazing-spider-man-1 name: 'The Amazing Spider-Man #1' issue_number: '1' release_date: '2018-07-11' image_url: 'https://cdn.versedb.com/issues/5432/cover_md.webp' is_nsfw: false publisher: 'Marvel Comics' series: id: 88 name: 'The Amazing Spider-Man' slug: the-amazing-spider-man start_year: 2018 - id: 2 position: 2 note: null created_at: '2024-01-15T10:31:00Z' updated_at: '2024-01-15T10:31:00Z' variant_id: null entity_type: issues entity: id: 5433 slug: the-amazing-spider-man-2 name: 'The Amazing Spider-Man #2' issue_number: '2' release_date: '2018-07-25' image_url: 'https://cdn.versedb.com/issues/5433/cover_md.webp' is_nsfw: false publisher: 'Marvel Comics' series: id: 88 name: 'The Amazing Spider-Man' slug: the-amazing-spider-man start_year: 2018 created_at: '2024-01-15T10:30:00Z' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Private List' content: application/json: schema: type: object properties: message: type: string examples: - 'This list is private.' examples: - message: 'This list is private.' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Not Found' examples: - message: 'Not Found' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists put: summary: 'Update list.' operationId: updateList description: "Updates a list's metadata. Wishlists can only update privacy settings." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 101 title: type: string examples: - 'Updated Title' description: type: string examples: - 'Updated description' examples: - data: id: 101 title: 'Updated Title' description: 'Updated description' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Unauthorized content: application/json: schema: type: object properties: message: type: string examples: - 'This action is unauthorized.' examples: - message: 'This action is unauthorized.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists requestBody: required: false content: application/json: schema: type: object properties: title: type: string description: 'List title (max 100 chars).' examples: - 'Updated Title' description: type: - string - 'null' description: 'List description (max 2000 chars).' examples: - 'Updated description' is_ranked: type: boolean description: 'Whether items are ranked.' examples: - false is_private: type: boolean description: 'Whether the list is private. Non-wishlist private lists require a Pro subscription.' examples: - true status: type: string description: 'The list status. One of: `published`, `draft`.' enum: - published - draft examples: - published rules: type: object description: 'A replacement smart-list rule. Accepted only on a list that was created rule-built — a rule is tuned here, never introduced or removed. Fetch the field catalog from `/lists/rule-vocabulary` and validate a draft against `/lists/rule-preview`.' properties: {} examples: - version: 2 match: all: - field: launch_date op: within_last value: count: 3 unit: months sort: field: launch_date direction: desc limit: 500 delete: summary: 'Delete list.' operationId: deleteList description: 'Permanently deletes a list and all its items. Wishlists cannot be deleted.' parameters: [] responses: '204': description: Success headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Forbidden. The authenticated user may not perform this action.' content: application/json: schema: oneOf: - description: Wishlist type: object properties: message: type: string examples: - 'Wishlists cannot be deleted.' examples: - message: 'Wishlists cannot be deleted.' - description: Unauthorized type: object properties: message: type: string examples: - 'You are not authorized to delete this list.' examples: - message: 'You are not authorized to delete this list.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 '/api/v1/users/{user_id}/lists': get: summary: "Get user's lists." operationId: getUsersLists description: "Returns a user's public lists. If viewing your own profile, also includes private lists." parameters: - in: query name: entity_type description: 'Filter by entity type (issues, series, etc.).' required: false schema: type: string description: 'Filter by entity type (issues, series, etc.).' examples: - issues - in: query name: sort description: 'Sort order (newest, popular, most_saved).' required: false schema: type: string description: 'Sort order (newest, popular, most_saved).' examples: - newest - in: query name: limit description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 101 title: type: string examples: - 'My Reading List' entity_type: type: string examples: - issues items_count: type: integer examples: - 15 is_private: type: boolean examples: - false user: type: object properties: id: type: integer examples: - 123 username: type: string examples: - comic_fan examples: - - id: 101 title: 'My Reading List' entity_type: issues items_count: 15 is_private: false user: id: 123 username: comic_fan meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 5 examples: - data: - id: 101 title: 'My Reading List' entity_type: issues items_count: 15 is_private: false user: id: 123 username: comic_fan meta: current_page: 1 last_page: 1 per_page: 20 total: 5 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists parameters: - in: path name: user_id description: 'The user ID.' required: true schema: type: integer examples: - 123 '/api/v1/lists/{list_id}/convert-to-mixed': post: summary: 'Open a list to any type.' operationId: openAListToAnyType description: "One-way: broadens a single-type list so it can hold items of any type. Existing items keep\ntheir own type. It cannot be narrowed back, and a wishlist already holds any type." parameters: [] responses: '200': description: Converted content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 101 entity_type: type: string examples: - mixed examples: - data: id: 101 entity_type: mixed headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Unauthorized content: application/json: schema: type: object properties: message: type: string examples: - 'This action is unauthorized.' examples: - message: 'This action is unauthorized.' '422': description: 'Not convertible' content: application/json: schema: type: object properties: message: type: string examples: - 'This list already holds any type.' examples: - message: 'This list already holds any type.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 '/api/v1/lists/{list_id}/stop-rule': post: summary: 'Stop a list updating itself.' operationId: stopAListUpdatingItself description: "One-way: drops a smart list's rule and keeps every item the last refresh left,\nhanding the contents back for editing by hand. A rule is only ever attached when\na list is created, so it cannot be put back." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 101 entity_type: type: string examples: - mixed examples: - data: id: 101 entity_type: mixed headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '422': description: 'Not rule-built' content: application/json: schema: type: object properties: message: type: string examples: - 'This list is not built from a rule.' examples: - message: 'This list is not built from a rule.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 '/api/v1/lists/{list_id}/merge': post: summary: 'Merge a list into this one.' operationId: mergeAListIntoThisOne description: "Pulls every item from the source list into this (destination) list, skipping items already\npresent (by entity + variant) and appending the rest. Both lists must be owned by the\nauthenticated user. Merging items of a different type opens this list to any type." parameters: [] responses: '200': description: Merged content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 101 title: type: string examples: - 'Best Batman Runs' item_types: type: array items: type: string examples: - - issues merge: type: object properties: moved: type: integer examples: - 4 skipped_duplicates: type: integer examples: - 1 converted_to_mixed: type: boolean examples: - false source_deleted: type: boolean examples: - false examples: - data: id: 101 title: 'Best Batman Runs' item_types: - issues merge: moved: 4 skipped_duplicates: 1 converted_to_mixed: false source_deleted: false headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Unauthorized content: application/json: schema: type: object properties: message: type: string examples: - 'You can only merge into your own lists.' examples: - message: 'You can only merge into your own lists.' '422': description: 'Invalid merge' content: application/json: schema: type: object properties: message: type: string examples: - 'The source list has no items to merge.' examples: - message: 'The source list has no items to merge.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists requestBody: required: true content: application/json: schema: type: object properties: source_list_id: type: integer description: 'The list to merge in.' examples: - 207 delete_source: type: boolean description: 'Delete the source list after merging. Defaults to false.' examples: - false required: - source_list_id parameters: - in: path name: list_id description: 'The destination list ID.' required: true schema: type: integer examples: - 101 '/api/v1/lists/{list_id}/items': post: summary: 'Add item to list.' operationId: addItemToList description: 'Adds an entity to a list. Free users: 100 items/list, PRO users: 500 items/list.' parameters: [] responses: '201': description: Added content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 501 position: type: integer examples: - 1 note: type: string examples: - 'My favorite issue!' created_at: type: string examples: - '2024-01-15T10:30:00Z' updated_at: type: string examples: - '2024-01-15T10:30:00Z' variant_id: type: integer examples: - 7 variant: type: object properties: id: type: integer examples: - 7 name: type: string examples: - 'Virgin Variant' cover_image_url: type: string examples: - 'https://cdn.versedb.com/variants/7/cover_md.webp' entity_type: type: string examples: - issues entity: type: object properties: id: type: integer examples: - 5432 slug: type: string examples: - the-amazing-spider-man-1 name: type: string examples: - 'The Amazing Spider-Man #1' issue_number: type: string examples: - '1' release_date: type: string examples: - '2018-07-11' image_url: type: string examples: - 'https://cdn.versedb.com/issues/5432/cover_md.webp' is_nsfw: type: boolean examples: - false publisher: type: string examples: - 'Marvel Comics' series: type: object properties: id: type: integer examples: - 88 name: type: string examples: - 'The Amazing Spider-Man' slug: type: string examples: - the-amazing-spider-man start_year: type: integer examples: - 2018 examples: - data: id: 501 position: 1 note: 'My favorite issue!' created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' variant_id: 7 variant: id: 7 name: 'Virgin Variant' cover_image_url: 'https://cdn.versedb.com/variants/7/cover_md.webp' entity_type: issues entity: id: 5432 slug: the-amazing-spider-man-1 name: 'The Amazing Spider-Man #1' issue_number: '1' release_date: '2018-07-11' image_url: 'https://cdn.versedb.com/issues/5432/cover_md.webp' is_nsfw: false publisher: 'Marvel Comics' series: id: 88 name: 'The Amazing Spider-Man' slug: the-amazing-spider-man start_year: 2018 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Item Limit' content: application/json: schema: type: object properties: message: type: string examples: - 'This list has reached its item limit. Upgrade to PRO for more.' examples: - message: 'This list has reached its item limit. Upgrade to PRO for more.' '409': description: 'Already Exists' content: application/json: schema: type: object properties: message: type: string examples: - 'This item is already in the list.' item: type: object properties: id: type: integer examples: - 501 position: type: integer examples: - 1 note: type: string examples: - 'My favorite issue!' created_at: type: string examples: - '2024-01-15T10:30:00Z' updated_at: type: string examples: - '2024-01-15T10:30:00Z' variant_id: type: integer examples: - 7 variant: type: object properties: id: type: integer examples: - 7 name: type: string examples: - 'Virgin Variant' cover_image_url: type: string examples: - 'https://cdn.versedb.com/variants/7/cover_md.webp' entity_type: type: string examples: - issues entity: type: object properties: id: type: integer examples: - 5432 slug: type: string examples: - the-amazing-spider-man-1 name: type: string examples: - 'The Amazing Spider-Man #1' issue_number: type: string examples: - '1' release_date: type: string examples: - '2018-07-11' image_url: type: string examples: - 'https://cdn.versedb.com/issues/5432/cover_md.webp' is_nsfw: type: boolean examples: - false publisher: type: string examples: - 'Marvel Comics' series: type: object properties: id: type: integer examples: - 88 name: type: string examples: - 'The Amazing Spider-Man' slug: type: string examples: - the-amazing-spider-man start_year: type: integer examples: - 2018 examples: - message: 'This item is already in the list.' item: id: 501 position: 1 note: 'My favorite issue!' created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' variant_id: 7 variant: id: 7 name: 'Virgin Variant' cover_image_url: 'https://cdn.versedb.com/variants/7/cover_md.webp' entity_type: issues entity: id: 5432 slug: the-amazing-spider-man-1 name: 'The Amazing Spider-Man #1' issue_number: '1' release_date: '2018-07-11' image_url: 'https://cdn.versedb.com/issues/5432/cover_md.webp' is_nsfw: false publisher: 'Marvel Comics' series: id: 88 name: 'The Amazing Spider-Man' slug: the-amazing-spider-man start_year: 2018 '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists requestBody: required: true content: application/json: schema: type: object properties: entity_id: type: integer description: 'The entity ID to add.' examples: - 5432 entity_type: type: - string - 'null' description: 'Required when the list holds any type: the type of the entity being added (issues, series, characters, creators, story_arcs, teams). Ignored on a single-type list.' examples: - issues variant_id: type: - integer - 'null' description: 'Optional cover variant of the issue (issue items only, must belong to entity_id). Omit for "any cover".' examples: - 7 position: type: - integer - 'null' description: 'Position in list (auto-assigned if omitted).' examples: - 1 note: type: - string - 'null' description: 'Personal note for this item (max 500 chars).' examples: - 'My favorite issue!' required: - entity_id parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 '/api/v1/lists/{list_id}/items/{item_id}': delete: summary: 'Remove item from list.' operationId: removeItemFromList description: "Removes an item from a list. Other items' positions are automatically adjusted." parameters: [] responses: '204': description: Success headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: Unauthorized content: application/json: schema: type: object properties: message: type: string examples: - 'You are not authorized to remove items from this list.' examples: - message: 'You are not authorized to remove items from this list.' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Item does not belong to this list.' examples: - message: 'Item does not belong to this list.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 - in: path name: item_id description: 'The list item ID.' required: true schema: type: integer examples: - 501 '/api/v1/lists/{list_id}/items/reorder': put: summary: 'Reorder items.' operationId: reorderItems description: 'Reorders items in a list by providing the new order of item IDs.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: message: type: string examples: - 'Items reordered successfully.' items: type: array items: type: object properties: id: type: integer examples: - 503 position: type: integer examples: - 1 note: type: - string - 'null' examples: - null entity_type: type: string examples: - issues entity: type: object properties: id: type: integer examples: - 5432 name: type: string examples: - 'The Amazing Spider-Man #1' issue_number: type: string examples: - '1' image_url: type: string examples: - 'https://...' examples: - - id: 503 position: 1 note: null entity_type: issues entity: id: 5432 name: 'The Amazing Spider-Man #1' issue_number: '1' image_url: 'https://...' - id: 501 position: 2 note: null entity_type: issues entity: id: 5433 name: 'The Amazing Spider-Man #2' issue_number: '2' image_url: 'https://...' - id: 502 position: 3 note: null entity_type: issues entity: id: 5434 name: 'The Amazing Spider-Man #3' issue_number: '3' image_url: 'https://...' examples: - message: 'Items reordered successfully.' items: - id: 503 position: 1 note: null entity_type: issues entity: id: 5432 name: 'The Amazing Spider-Man #1' issue_number: '1' image_url: 'https://...' - id: 501 position: 2 note: null entity_type: issues entity: id: 5433 name: 'The Amazing Spider-Man #2' issue_number: '2' image_url: 'https://...' - id: 502 position: 3 note: null entity_type: issues entity: id: 5434 name: 'The Amazing Spider-Man #3' issue_number: '3' image_url: 'https://...' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists requestBody: required: true content: application/json: schema: type: object properties: item_ids: type: array description: 'Array of item IDs in desired order.' items: type: integer examples: - - 503 - 501 - 502 required: - item_ids parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 '/api/v1/lists/{list_id}/save': post: summary: 'Save list.' operationId: saveList description: "Saves a list to the user's saved lists for quick access. Cannot save your own lists." parameters: [] responses: '200': description: 'Already Saved' content: application/json: schema: type: object properties: message: type: string examples: - 'List is already saved.' saved: type: boolean examples: - true examples: - message: 'List is already saved.' saved: true headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '201': description: Saved content: application/json: schema: type: object properties: message: type: string examples: - 'List saved successfully.' saved: type: boolean examples: - true saves_count: type: integer examples: - 90 examples: - message: 'List saved successfully.' saved: true saves_count: 90 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Own List' content: application/json: schema: type: object properties: message: type: string examples: - 'You cannot save your own list.' examples: - message: 'You cannot save your own list.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists delete: summary: 'Unsave list.' operationId: unsaveList description: "Removes a list from the user's saved lists." parameters: [] responses: '200': description: Success. content: application/json: schema: oneOf: - description: Unsaved type: object properties: message: type: string examples: - 'List unsaved successfully.' saved: type: boolean examples: - false saves_count: type: integer examples: - 89 examples: - message: 'List unsaved successfully.' saved: false saves_count: 89 - description: 'Not Saved' type: object properties: message: type: string examples: - 'List is not saved.' saved: type: boolean examples: - false examples: - message: 'List is not saved.' saved: false headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 '/api/v1/lists/{list_id}/like': post: summary: 'Like list.' operationId: likeList description: 'Likes a list. Cannot like your own lists.' parameters: [] responses: '200': description: 'Already Liked' content: application/json: schema: type: object properties: message: type: string examples: - 'List is already liked.' liked: type: boolean examples: - true examples: - message: 'List is already liked.' liked: true headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '201': description: Liked content: application/json: schema: type: object properties: message: type: string examples: - 'List liked successfully.' liked: type: boolean examples: - true likes_count: type: integer examples: - 151 examples: - message: 'List liked successfully.' liked: true likes_count: 151 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Own List' content: application/json: schema: type: object properties: message: type: string examples: - 'You cannot like your own list.' examples: - message: 'You cannot like your own list.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists delete: summary: 'Unlike list.' operationId: unlikeList description: "Removes the user's like from a list." parameters: [] responses: '200': description: Success. content: application/json: schema: oneOf: - description: Unliked type: object properties: message: type: string examples: - 'List unliked successfully.' liked: type: boolean examples: - false likes_count: type: integer examples: - 150 examples: - message: 'List unliked successfully.' liked: false likes_count: 150 - description: 'Not Liked' type: object properties: message: type: string examples: - 'List is not liked.' liked: type: boolean examples: - false examples: - message: 'List is not liked.' liked: false headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - Lists parameters: - in: path name: list_id description: 'The list ID.' required: true schema: type: integer examples: - 101 '/api/v1/lookup/upc/{upc}': get: summary: 'Lookup by UPC.' operationId: lookupByUPC description: "Find an issue by its UPC barcode (typically 12-17 digits).\nReturns full issue details including series information." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 5432 slug: type: string examples: - amazing-spider-man-1 series_id: type: integer examples: - 123 title_id: type: integer examples: - 45 issue_number: type: string examples: - '1' name: type: string examples: - 'The Amazing Spider-Man #1' description: type: string examples: - 'Nick Spencer and Ryan Ottley begin a new era...' release_date: type: string examples: - '2018-07-11' cover_date: type: string examples: - '2018-09-01' cover_url: type: string examples: - 'https://...' upc: type: string examples: - '75960608936700111' series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' slug: type: string examples: - amazing-spider-man-2018 start_year: type: integer examples: - 2018 volume_number: type: integer examples: - 5 publisher: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Marvel slug: type: string examples: - marvel suggested_variant_id: type: integer examples: - 789 variants: type: array items: type: object properties: variant_id: type: - string - 'null' examples: - null variant_name: type: string examples: - 'Cover A' cover_url: type: string examples: - 'https://...' examples: - - variant_id: null variant_name: 'Cover A' cover_url: 'https://...' - variant_id: 789 variant_name: 'Cover B' cover_url: 'https://...' examples: - data: id: 5432 slug: amazing-spider-man-1 series_id: 123 title_id: 45 issue_number: '1' name: 'The Amazing Spider-Man #1' description: 'Nick Spencer and Ryan Ottley begin a new era...' release_date: '2018-07-11' cover_date: '2018-09-01' cover_url: 'https://...' upc: '75960608936700111' series: id: 123 name: 'Amazing Spider-Man' slug: amazing-spider-man-2018 start_year: 2018 volume_number: 5 publisher: id: 1 name: Marvel slug: marvel suggested_variant_id: 789 variants: - variant_id: null variant_name: 'Cover A' cover_url: 'https://...' - variant_id: 789 variant_name: 'Cover B' cover_url: 'https://...' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Missing Ability' content: application/json: schema: type: object properties: message: type: string examples: - Unauthorized examples: - message: Unauthorized '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'No issue found with UPC: 75960608936700111' examples: - message: 'No issue found with UPC: 75960608936700111' '409': description: 'Multiple Matches' content: application/json: schema: type: object properties: message: type: string examples: - 'Multiple issues share UPC: 075960608936. Pick one below.' count: type: integer examples: - 3 total_count: type: integer examples: - 3 matches: type: array items: type: object properties: issue_id: type: integer examples: - 5432 series_name: type: string examples: - 'Amazing Spider-Man' series_id: type: integer examples: - 123 issue_number: type: string examples: - '1' cover_url: type: string examples: - 'https://...' variant_name: type: - string - 'null' examples: - null suggested_variant_id: type: - string - 'null' examples: - null variants: type: array items: type: object properties: variant_id: type: - string - 'null' examples: - null variant_name: type: string examples: - 'Cover A' cover_url: type: string examples: - 'https://...' examples: - - variant_id: null variant_name: 'Cover A' cover_url: 'https://...' publisher_name: type: string examples: - Marvel release_date: type: string examples: - '1990-04-01' start_year: type: integer examples: - 1963 examples: - - issue_id: 5432 series_name: 'Amazing Spider-Man' series_id: 123 issue_number: '1' cover_url: 'https://...' variant_name: null suggested_variant_id: null variants: - variant_id: null variant_name: 'Cover A' cover_url: 'https://...' publisher_name: Marvel release_date: '1990-04-01' start_year: 1963 examples: - message: 'Multiple issues share UPC: 075960608936. Pick one below.' count: 3 total_count: 3 matches: - issue_id: 5432 series_name: 'Amazing Spider-Man' series_id: 123 issue_number: '1' cover_url: 'https://...' variant_name: null suggested_variant_id: null variants: - variant_id: null variant_name: 'Cover A' cover_url: 'https://...' publisher_name: Marvel release_date: '1990-04-01' start_year: 1963 '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Barcode Lookup' parameters: - in: path name: upc description: 'The UPC barcode.' required: true schema: type: string examples: - '75960608936700111' '/api/v1/lookup/isbn/{isbn}': get: summary: 'Lookup by ISBN.' operationId: lookupByISBN description: "Find an issue by its ISBN (10 or 13 digits, with or without dashes).\nCommonly used for trade paperbacks and hardcovers.\nReturns full issue details including series information." parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 8765 slug: type: string examples: - spider-man-life-story-tp series_id: type: integer examples: - 456 title_id: type: integer examples: - 45 issue_number: type: string examples: - '1' name: type: string examples: - 'Spider-Man: Life Story TP' description: type: string examples: - 'A story of Peter Parker...' release_date: type: string examples: - '2019-10-02' isbn: type: string examples: - 978-1302913847 format: type: string examples: - trade_paperback series: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Spider-Man: Life Story' slug: type: string examples: - spider-man-life-story publisher: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Marvel slug: type: string examples: - marvel examples: - data: id: 8765 slug: spider-man-life-story-tp series_id: 456 title_id: 45 issue_number: '1' name: 'Spider-Man: Life Story TP' description: 'A story of Peter Parker...' release_date: '2019-10-02' isbn: 978-1302913847 format: trade_paperback series: id: 456 name: 'Spider-Man: Life Story' slug: spider-man-life-story publisher: id: 1 name: Marvel slug: marvel headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Missing Ability' content: application/json: schema: type: object properties: message: type: string examples: - Unauthorized examples: - message: Unauthorized '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'No issue found with ISBN: 978-1302913847' examples: - message: 'No issue found with ISBN: 978-1302913847' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - 'Barcode Lookup' parameters: - in: path name: isbn description: 'The ISBN (10 or 13 digits).' required: true schema: type: string examples: - 978-1302913847 /api/v1/user: get: summary: 'Get the authenticated user.' operationId: getTheAuthenticatedUser description: 'Returns the profile of the user the token belongs to.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'John Doe' username: type: string examples: - comic_fan_42 email: type: string examples: - john@example.com bio: type: string examples: - 'Comic collector since 1985' profile_image_url: type: string examples: - 'https://r2.versedb.com/uploads/users/comic-fan-42/comic-fan-42-abc123-profile_md.webp' glow_color: type: string examples: - '#FF5733' banner_url: type: - string - 'null' examples: - null country_code: type: string examples: - US city: type: string examples: - 'New York' region: type: string examples: - NY postal_code: type: string examples: - '10001' formatted_location: type: string examples: - 'New York, NY' is_private: type: boolean examples: - false is_wishlist_public: type: boolean examples: - true show_nsfw_warnings: type: boolean examples: - true can_view_nsfw: type: boolean examples: - true show_reading_list: type: boolean examples: - true show_collection: type: boolean examples: - true show_activity: type: boolean examples: - true show_spoilers: type: boolean examples: - false preferred_mediums: type: array items: type: string examples: - - comic preferred_genres: type: array examples: - [] preferred_languages: type: array items: type: string examples: - - en locale: type: string examples: - en is_pro: type: boolean examples: - true level: type: integer examples: - 5 xp: type: integer examples: - 1200 xp_for_next_level: type: integer examples: - 2000 xp_progress_percent: type: number examples: - 60.0 contributions_count: type: integer examples: - 42 level_name: type: string examples: - Collector has_password: type: boolean examples: - true created_at: type: string examples: - '2024-01-15T10:30:00.000000Z' updated_at: type: string examples: - '2026-06-20T14:32:00.000000Z' examples: - data: id: 123 name: 'John Doe' username: comic_fan_42 email: john@example.com bio: 'Comic collector since 1985' profile_image_url: 'https://r2.versedb.com/uploads/users/comic-fan-42/comic-fan-42-abc123-profile_md.webp' glow_color: '#FF5733' banner_url: null country_code: US city: 'New York' region: NY postal_code: '10001' formatted_location: 'New York, NY' is_private: false is_wishlist_public: true show_nsfw_warnings: true can_view_nsfw: true show_reading_list: true show_collection: true show_activity: true show_spoilers: false preferred_mediums: - comic preferred_genres: [] preferred_languages: - en locale: en is_pro: true level: 5 xp: 1200 xp_for_next_level: 2000 xp_progress_percent: 60.0 contributions_count: 42 level_name: Collector has_password: true created_at: '2024-01-15T10:30:00.000000Z' updated_at: '2026-06-20T14:32:00.000000Z' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User /api/v1/user/collections: get: summary: 'List collection.' operationId: listCollection description: "Returns all issues in the user's collection with series and publisher info." parameters: - in: query name: per_page description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 - in: query name: page description: 'Page number.' required: false schema: type: integer description: 'Page number.' examples: - 1 - in: query name: search description: 'Filter by issue name, issue number, or series name.' required: false schema: type: string description: 'Filter by issue name, issue number, or series name.' examples: - spider - in: query name: format description: 'Filter by stored format.' required: false schema: type: string description: 'Filter by stored format.' examples: - single - in: query name: graded description: 'Filter to graded (true) or raw (false) copies.' required: false schema: type: boolean description: 'Filter to graded (true) or raw (false) copies.' examples: - true - in: query name: is_signed description: 'Filter to signed (true) or unsigned (false) copies.' required: false schema: type: boolean description: 'Filter to signed (true) or unsigned (false) copies.' examples: - true - in: query name: condition description: 'Filter by condition grade code.' required: false schema: type: string description: 'Filter by condition grade code.' examples: - NM - in: query name: for_sale description: 'Filter to copies marked for sale.' required: false schema: type: boolean description: 'Filter to copies marked for sale.' examples: - true - in: query name: for_trade description: 'Filter to copies marked for trade.' required: false schema: type: boolean description: 'Filter to copies marked for trade.' examples: - true - in: query name: read_status description: 'Filter by read state. One of: read, unread.' required: false schema: type: string description: 'Filter by read state. One of: read, unread.' examples: - unread - in: query name: publisher_id description: 'Filter to issues from a publisher.' required: false schema: type: integer description: 'Filter to issues from a publisher.' examples: - 1 - in: query name: series_id description: 'Filter to copies of issues in a series.' required: false schema: type: integer description: 'Filter to copies of issues in a series.' examples: - 123 - in: query name: grade_min description: 'Filter to copies with a numeric grade at or above this value.' required: false schema: type: number description: 'Filter to copies with a numeric grade at or above this value.' examples: - 9.0 - in: query name: grade_max description: 'Filter to copies with a numeric grade at or below this value.' required: false schema: type: number description: 'Filter to copies with a numeric grade at or below this value.' examples: - 9.8 - in: query name: sort_by description: 'Sort field. One of: date_added, title, release_date, estimated_value, price_paid.' required: false schema: type: string description: 'Sort field. One of: date_added, title, release_date, estimated_value, price_paid.' examples: - title - in: query name: sort_order description: 'Sort direction. One of: asc, desc.' required: false schema: type: string description: 'Sort direction. One of: asc, desc.' examples: - asc responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 1001 user_id: type: integer examples: - 42 collectable_type: type: string examples: - Issue collectable_id: type: integer examples: - 5432 variant_id: type: - string - 'null' examples: - null condition: type: string examples: - NM purchased_at: type: string examples: - '2024-01-15' notes: type: string examples: - 'First print' format: type: string examples: - single storage_location: type: string examples: - 'Long box 3' price_paid: type: number examples: - 3.99 is_variant: type: boolean examples: - false variant_description: type: - string - 'null' examples: - null variant_type: type: - string - 'null' examples: - null graded: type: boolean examples: - true grade_score: type: string examples: - '9.8' grading_company: type: string examples: - CGC grading_number: type: string examples: - '1234567001' label_type: type: string examples: - universal page_quality: type: string examples: - white grader_notes: type: - string - 'null' examples: - null purchase_source: type: string examples: - lcs comic_shop_id: type: integer examples: - 17 comic_shop: type: object properties: id: type: integer examples: - 17 name: type: string examples: - 'Comic Corner' slug: type: string examples: - comic-corner city: type: string examples: - Portland state_province: type: string examples: - OR acquisition_method: type: string examples: - purchased is_signed: type: boolean examples: - false signed_by: type: - string - 'null' examples: - null signature_witness: type: - string - 'null' examples: - null signature_authenticated: type: boolean examples: - false is_cgc_ss: type: boolean examples: - false print_number: type: integer examples: - 1 estimated_value: type: number examples: - 25.0 value_last_updated: type: string examples: - '2024-06-01T00:00:00Z' for_sale: type: boolean examples: - false for_trade: type: boolean examples: - false is_public: type: boolean examples: - true cover_scan_url: type: - string - 'null' examples: - null cover_scan_url_lg: type: - string - 'null' examples: - null cover_scan_uploaded_at: type: - string - 'null' examples: - null created_at: type: string examples: - '2024-01-15T10:30:00Z' updated_at: type: string examples: - '2024-01-15T10:30:00Z' collectable: type: object properties: id: type: integer examples: - 5432 slug: type: string examples: - example-series-1 series_id: type: integer examples: - 123 issue_number: type: string examples: - '1' name: type: string examples: - 'First Issue' cover_date: type: string examples: - '2023-11-01' release_date: type: string examples: - '2023-11-08' foc_date: type: string examples: - '2023-10-16' cover_url: type: string examples: - 'https://versedb.com/storage/issues/5432/cover_lg.jpg' images: type: object properties: thumb: type: string examples: - 'https://versedb.com/storage/issues/5432/thumb.jpg' cover_sm: type: string examples: - 'https://versedb.com/storage/issues/5432/cover_sm.jpg' cover_md: type: string examples: - 'https://versedb.com/storage/issues/5432/cover_md.jpg' cover_lg: type: string examples: - 'https://versedb.com/storage/issues/5432/cover_lg.jpg' is_reprint: type: boolean examples: - false content_rating_label: type: - string - 'null' examples: - null min_age: type: - string - 'null' examples: - null is_nsfw: type: boolean examples: - false average_rating: type: number examples: - 4.5 series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Example Series' slug: type: string examples: - example-series start_year: type: integer examples: - 2023 end_year: type: - string - 'null' examples: - null volume_number: type: integer examples: - 1 publication_type: type: string examples: - ongoing format: type: string examples: - single cached_issues_count: type: integer examples: - 12 cover_url: type: string examples: - 'https://versedb.com/storage/series/123/cover_lg.jpg' images: type: object properties: cover_sm: type: string examples: ['https://versedb.com/storage/series/123/cover_sm.jpg'] cover_md: type: string examples: ['https://versedb.com/storage/series/123/cover_md.jpg'] cover_lg: type: string examples: ['https://versedb.com/storage/series/123/cover_lg.jpg'] publisher_name: type: string examples: - 'Example Publisher' key_issue_reasons: type: array items: type: object properties: id: type: integer examples: - 7 name: type: string examples: - 'First appearance' category: type: string examples: - appearance slug: type: string examples: - first-appearance notes: type: - string - 'null' examples: - null examples: - - id: 7 name: 'First appearance' category: appearance slug: first-appearance notes: null examples: - - id: 1001 user_id: 42 collectable_type: Issue collectable_id: 5432 variant_id: null condition: NM purchased_at: '2024-01-15' notes: 'First print' format: single storage_location: 'Long box 3' price_paid: 3.99 is_variant: false variant_description: null variant_type: null graded: true grade_score: '9.8' grading_company: CGC grading_number: '1234567001' label_type: universal page_quality: white grader_notes: null purchase_source: lcs comic_shop_id: 17 comic_shop: id: 17 name: 'Comic Corner' slug: comic-corner city: Portland state_province: OR acquisition_method: purchased is_signed: false signed_by: null signature_witness: null signature_authenticated: false is_cgc_ss: false print_number: 1 estimated_value: 25 value_last_updated: '2024-06-01T00:00:00Z' for_sale: false for_trade: false is_public: true cover_scan_url: null cover_scan_url_lg: null cover_scan_uploaded_at: null created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' collectable: id: 5432 slug: example-series-1 series_id: 123 issue_number: '1' name: 'First Issue' cover_date: '2023-11-01' release_date: '2023-11-08' foc_date: '2023-10-16' cover_url: 'https://versedb.com/storage/issues/5432/cover_lg.jpg' images: thumb: 'https://versedb.com/storage/issues/5432/thumb.jpg' cover_sm: 'https://versedb.com/storage/issues/5432/cover_sm.jpg' cover_md: 'https://versedb.com/storage/issues/5432/cover_md.jpg' cover_lg: 'https://versedb.com/storage/issues/5432/cover_lg.jpg' is_reprint: false content_rating_label: null min_age: null is_nsfw: false average_rating: 4.5 series: id: 123 name: 'Example Series' slug: example-series start_year: 2023 end_year: null volume_number: 1 publication_type: ongoing format: single cached_issues_count: 12 cover_url: 'https://versedb.com/storage/series/123/cover_lg.jpg' images: cover_sm: 'https://versedb.com/storage/series/123/cover_sm.jpg' cover_md: 'https://versedb.com/storage/series/123/cover_md.jpg' cover_lg: 'https://versedb.com/storage/series/123/cover_lg.jpg' publisher_name: 'Example Publisher' key_issue_reasons: - id: 7 name: 'First appearance' category: appearance slug: first-appearance notes: null links: type: object properties: first: type: string examples: - ... last: type: string examples: - ... prev: type: - string - 'null' examples: - null next: type: string examples: - ... meta: type: object properties: current_page: type: integer examples: - 1 from: type: integer examples: - 1 last_page: type: integer examples: - 5 path: type: string examples: - ... per_page: type: integer examples: - 20 to: type: integer examples: - 20 total: type: integer examples: - 100 examples: - data: - id: 1001 user_id: 42 collectable_type: Issue collectable_id: 5432 variant_id: null condition: NM purchased_at: '2024-01-15' notes: 'First print' format: single storage_location: 'Long box 3' price_paid: 3.99 is_variant: false variant_description: null variant_type: null graded: true grade_score: '9.8' grading_company: CGC grading_number: '1234567001' label_type: universal page_quality: white grader_notes: null purchase_source: lcs comic_shop_id: 17 comic_shop: id: 17 name: 'Comic Corner' slug: comic-corner city: Portland state_province: OR acquisition_method: purchased is_signed: false signed_by: null signature_witness: null signature_authenticated: false is_cgc_ss: false print_number: 1 estimated_value: 25.0 value_last_updated: '2024-06-01T00:00:00Z' for_sale: false for_trade: false is_public: true cover_scan_url: null cover_scan_url_lg: null cover_scan_uploaded_at: null created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' collectable: id: 5432 slug: example-series-1 series_id: 123 issue_number: '1' name: 'First Issue' cover_date: '2023-11-01' release_date: '2023-11-08' foc_date: '2023-10-16' cover_url: 'https://versedb.com/storage/issues/5432/cover_lg.jpg' images: thumb: 'https://versedb.com/storage/issues/5432/thumb.jpg' cover_sm: 'https://versedb.com/storage/issues/5432/cover_sm.jpg' cover_md: 'https://versedb.com/storage/issues/5432/cover_md.jpg' cover_lg: 'https://versedb.com/storage/issues/5432/cover_lg.jpg' is_reprint: false content_rating_label: null min_age: null is_nsfw: false average_rating: 4.5 series: id: 123 name: 'Example Series' slug: example-series start_year: 2023 end_year: null volume_number: 1 publication_type: ongoing format: single cached_issues_count: 12 cover_url: 'https://versedb.com/storage/series/123/cover_lg.jpg' images: cover_sm: 'https://versedb.com/storage/series/123/cover_sm.jpg' cover_md: 'https://versedb.com/storage/series/123/cover_md.jpg' cover_lg: 'https://versedb.com/storage/series/123/cover_lg.jpg' publisher_name: 'Example Publisher' key_issue_reasons: - id: 7 name: 'First appearance' category: appearance slug: first-appearance notes: null links: first: ... last: ... prev: null next: ... meta: current_page: 1 from: 1 last_page: 5 path: ... per_page: 20 to: 20 total: 100 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User '/api/v1/issues/{issue_id}/collection/check': get: summary: 'Check issue in collection.' operationId: checkIssueInCollection description: "Checks if an issue (optionally a specific variant) is in the user's collection." parameters: - in: query name: variant_id description: 'Specific variant ID to check (optional).' required: false schema: type: integer description: 'Specific variant ID to check (optional).' examples: - 789 responses: '200': description: Success. content: application/json: schema: oneOf: - description: 'In Collection' type: object properties: in_collection: type: boolean examples: - true is_unreleased: type: boolean examples: - false copies_count: type: integer examples: - 1 copies: type: array items: type: object properties: id: type: integer examples: - 1001 variant_id: type: integer examples: - 789 condition: type: string examples: - NM graded: type: boolean examples: - true grade_score: type: string examples: - '9.8' grading_company: type: string examples: - CGC is_signed: type: boolean examples: - false signed_by: type: - string - 'null' examples: - null is_cgc_ss: type: boolean examples: - false format: type: string examples: - single storage_location: type: string examples: - 'Long box 3' purchased_at: type: string examples: - '2024-01-15T00:00:00Z' notes: type: string examples: - 'First print' created_at: type: string examples: - '2024-01-15T10:30:00Z' examples: - - id: 1001 variant_id: 789 condition: NM graded: true grade_score: '9.8' grading_company: CGC is_signed: false signed_by: null is_cgc_ss: false format: single storage_location: 'Long box 3' purchased_at: '2024-01-15T00:00:00Z' notes: 'First print' created_at: '2024-01-15T10:30:00Z' data: type: object properties: id: type: integer examples: - 1001 condition: type: string examples: - NM price_paid: type: number examples: - 4.99 issue: type: object properties: id: type: integer examples: - 5432 name: type: string examples: - 'The Amazing Spider-Man #1' issue_number: type: string examples: - '1' examples: - in_collection: true is_unreleased: false copies_count: 1 copies: - id: 1001 variant_id: 789 condition: NM graded: true grade_score: '9.8' grading_company: CGC is_signed: false signed_by: null is_cgc_ss: false format: single storage_location: 'Long box 3' purchased_at: '2024-01-15T00:00:00Z' notes: 'First print' created_at: '2024-01-15T10:30:00Z' data: id: 1001 condition: NM price_paid: 4.99 issue: id: 5432 name: 'The Amazing Spider-Man #1' issue_number: '1' - description: 'Not in Collection' type: object properties: in_collection: type: boolean examples: - false is_unreleased: type: boolean examples: - false copies_count: type: integer examples: - 0 copies: type: array examples: - [] data: type: - string - 'null' examples: - null examples: - in_collection: false is_unreleased: false copies_count: 0 copies: [] data: null headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 '/api/v1/issues/{issue_id}/collection': post: summary: 'Add issue to collection.' operationId: addIssueToCollection description: "Adds an issue to the user's default collection. Works for all users (no PRO required).\nThis is the recommended endpoint for mobile collection management." parameters: [] responses: '201': description: Added content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 1001 issue: type: object properties: id: type: integer examples: - 5432 number: type: string examples: - '1' title: type: string examples: - 'First Issue' series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' variant_id: type: - string - 'null' examples: - null condition: type: string examples: - NM price_paid: type: number examples: - 4.99 notes: type: string examples: - 'First print, signed' was_on_wishlist: type: boolean examples: - true examples: - data: id: 1001 issue: id: 5432 number: '1' title: 'First Issue' series: id: 123 name: 'Amazing Spider-Man' variant_id: null condition: NM price_paid: 4.99 notes: 'First print, signed' was_on_wishlist: true headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '403': description: 'Account Pending Deletion' content: application/json: schema: type: object properties: error: type: string examples: - 'Cannot add to collection while account is pending deletion.' examples: - error: 'Cannot add to collection while account is pending deletion.' '422': description: 'Invalid Variant' content: application/json: schema: type: object properties: error: type: string examples: - 'Variant does not belong to this issue.' examples: - error: 'Variant does not belong to this issue.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: variant_id: type: - integer - 'null' description: 'Specific variant ID (optional).' examples: - 789 condition: type: - string - 'null' description: 'Condition grade (e.g., NM, VF, FN, VG, G, FR, PR).' examples: - NM notes: type: - string - 'null' description: 'Personal notes (max 1000 chars).' examples: - 'First print, signed' price_paid: type: - number - 'null' description: 'Price paid (max 999999.99).' examples: - 4.99 format: type: - string - 'null' description: 'Physical format of the copy.' enum: - standard - trade_paperback - hardcover - omnibus - deluxe_edition - annual - graphic_novel - digital - treasury - magazine - prestige - digest - other examples: - standard purchase_source: type: - string - 'null' description: 'Where the comic was purchased.' enum: - comic_shop - online_retailer - auction - convention - private_seller - subscription - digital_platform - second_hand_store - inheritance - gift - trade - other examples: - comic_shop comic_shop_id: type: - integer - 'null' description: 'ID of the specific comic shop the copy was purchased from. Self-reported; independent of purchase_source. Must match an existing stored value.' examples: - 412 acquisition_method: type: - string - 'null' description: 'How the comic was acquired.' enum: - purchase - trade - gift - inheritance - subscription - found - other examples: - purchase purchased_at: type: - string - 'null' description: 'Date of purchase (YYYY-MM-DD). Must be a valid date.' examples: - '2024-06-15' storage_location: type: - string - 'null' description: 'Where the comic is stored. Must not be greater than 255 characters.' examples: - 'Long box #3' is_signed: type: boolean description: 'Whether the comic is signed.' examples: - false signed_by: type: - string - 'null' description: 'Name(s) of the creator(s) who signed the comic. Free-text. Comma-separate multiple signers. Must not be greater than 255 characters.' examples: - 'Stan Lee' is_variant: type: boolean description: 'Whether this copy is a variant cover.' examples: - false variant_description: type: - string - 'null' description: 'Free-text description of the variant cover. Must not be greater than 500 characters.' examples: - 'Skottie Young baby variant' variant_type: type: - string - 'null' description: 'Variant classification (standard, cover_variant, retailer_exclusive, incentive_variant, ratio_variant, virgin_variant, etc.).' enum: - standard - cover_variant - retailer_exclusive - convention_exclusive - incentive_variant - ratio_variant - foil_variant - sketch_variant - virgin_variant - blank_variant - artist_variant - hologram_variant - glow_in_dark_variant - facsimile - reprint - other examples: - cover_variant graded: type: boolean description: 'Whether the comic is professionally graded.' examples: - false grade_score: type: - string - 'null' description: 'Numeric grade score (e.g. 9.8). Must not be greater than 10 characters.' examples: - '9.8' grading_company: type: - string - 'null' description: 'Grading company (CGC, CBCS, PGX, other, self_graded).' enum: - CGC - CBCS - PGX - other - self_graded examples: - CGC grading_number: type: - string - 'null' description: 'Grading certification number. Must not be greater than 50 characters.' examples: - '1234567890' label_type: type: - string - 'null' description: 'Slab label tier (e.g. universal, signature_series, restored, qualified).' enum: - universal - signature_series - qualified - restored - cgcxjsa - standard - verified_signature - signed - conserved examples: - universal page_quality: type: - string - 'null' description: 'Interior page color quality from the slab label.' enum: - white - off_white_to_white - off_white - cream_to_off_white - light_tan - tan - brittle examples: - white grader_notes: type: - string - 'null' description: 'Free-text notes printed on the slab label. Must not be greater than 2000 characters.' examples: - 'Marvel Value Stamp #16 intact' print_number: type: - string - 'null' description: 'Which print this copy is (1st, 2nd, 3rd, … or other).' enum: - 1st - 2nd - 3rd - 4th - 5th - 6th - 7th - 8th - 9th - 10th - other examples: - 1st signature_witness: type: - string - 'null' description: 'Authentication of the signature (CGC, CBCS, JSA, PSA/DNA, witnessed_in_person, unwitnessed, other).' enum: - CGC - CBCS - JSA - PSA/DNA - witnessed_in_person - unwitnessed - other examples: - witnessed_in_person estimated_value: type: - number - 'null' description: 'Current estimated value in dollars. Must be at least 0. Must not be greater than 999999.99.' examples: - 25.0 for_sale: type: boolean description: 'Whether the item is for sale.' examples: - false for_trade: type: boolean description: 'Whether the item is available for trade.' examples: - false is_public: type: boolean description: 'Whether this collection item is publicly visible. Defaults to true.' examples: - true patch: summary: 'Update collection item.' operationId: updateCollectionItem description: "Updates metadata on an existing collection entry for an issue.\nSupports partial updates: only send the fields you want to change." parameters: - in: query name: variant_id description: 'Specific variant ID to update (when user has multiple entries).' required: false schema: type: integer description: 'Specific variant ID to update (when user has multiple entries).' examples: - 789 - in: query name: collection_item_id description: 'Specific collection item ID to update.' required: false schema: type: integer description: 'Specific collection item ID to update.' examples: - 1001 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: object properties: id: type: integer examples: - 1001 condition: type: string examples: - NM price_paid: type: number examples: - 4.99 graded: type: boolean examples: - true examples: - data: id: 1001 condition: NM price_paid: 4.99 graded: true headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: error: type: string examples: - 'Issue not found in your collection.' examples: - error: 'Issue not found in your collection.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: variant_id: type: - integer - 'null' description: 'Link to a specific issue variant. Must belong to the issue. Must match an existing stored value.' examples: - 42 condition: type: - string - 'null' description: 'Comic condition grade (CGC scale).' enum: - MT - NM/MT - NM+ - NM - NM- - VF/NM - VF+ - VF - VF- - F/VF - F+ - F - F- - VG/F - VG+ - VG - VG- - G/VG - G - FR - PR examples: - NM x-speakeasy-enums: - Mint - NearMintMint - NearMintPlus - NearMint - NearMintMinus - VeryFineNearMint - VeryFinePlus - VeryFine - VeryFineMinus - FineVeryFine - FinePlus - Fine - FineMinus - VeryGoodFine - VeryGoodPlus - VeryGood - VeryGoodMinus - GoodVeryGood - Good - Fair - Poor notes: type: - string - 'null' description: 'User notes about this copy. Must not be greater than 1000 characters.' examples: - 'First print, great condition' price_paid: type: - number - 'null' description: 'Purchase price in dollars. Must be at least 0. Must not be greater than 999999.99.' examples: - 3.99 format: type: - string - 'null' description: 'Physical format of the copy.' enum: - standard - trade_paperback - hardcover - omnibus - deluxe_edition - annual - graphic_novel - digital - treasury - magazine - prestige - digest - other examples: - standard purchase_source: type: - string - 'null' description: 'Where the comic was purchased.' enum: - comic_shop - online_retailer - auction - convention - private_seller - subscription - digital_platform - second_hand_store - inheritance - gift - trade - other examples: - comic_shop comic_shop_id: type: - integer - 'null' description: 'ID of the specific comic shop the copy was purchased from. Self-reported; independent of purchase_source. Must match an existing stored value.' examples: - 412 acquisition_method: type: - string - 'null' description: 'How the comic was acquired.' enum: - purchase - trade - gift - inheritance - subscription - found - other examples: - purchase purchased_at: type: - string - 'null' description: 'Date of purchase (YYYY-MM-DD). Must be a valid date.' examples: - '2024-06-15' storage_location: type: - string - 'null' description: 'Where the comic is stored. Must not be greater than 255 characters.' examples: - 'Long box #3' is_signed: type: boolean description: 'Whether the comic is signed.' examples: - false signed_by: type: - string - 'null' description: 'Name(s) of the creator(s) who signed the comic. Free-text. Comma-separate multiple signers. Must not be greater than 255 characters.' examples: - 'Stan Lee' is_variant: type: boolean description: 'Whether this copy is a variant cover.' examples: - false variant_description: type: - string - 'null' description: 'Free-text description of the variant cover. Must not be greater than 500 characters.' examples: - 'Skottie Young baby variant' variant_type: type: - string - 'null' description: 'Variant classification (standard, cover_variant, retailer_exclusive, incentive_variant, ratio_variant, virgin_variant, etc.).' enum: - standard - cover_variant - retailer_exclusive - convention_exclusive - incentive_variant - ratio_variant - foil_variant - sketch_variant - virgin_variant - blank_variant - artist_variant - hologram_variant - glow_in_dark_variant - facsimile - reprint - other examples: - cover_variant graded: type: boolean description: 'Whether the comic is professionally graded.' examples: - false grade_score: type: - string - 'null' description: 'Numeric grade score (e.g. 9.8). Must not be greater than 10 characters.' examples: - '9.8' grading_company: type: - string - 'null' description: 'Grading company (CGC, CBCS, PGX, other, self_graded).' enum: - CGC - CBCS - PGX - other - self_graded examples: - CGC grading_number: type: - string - 'null' description: 'Grading certification number. Must not be greater than 50 characters.' examples: - '1234567890' label_type: type: - string - 'null' description: 'Slab label tier (e.g. universal, signature_series, restored, qualified).' enum: - universal - signature_series - qualified - restored - cgcxjsa - standard - verified_signature - signed - conserved examples: - universal page_quality: type: - string - 'null' description: 'Interior page color quality from the slab label.' enum: - white - off_white_to_white - off_white - cream_to_off_white - light_tan - tan - brittle examples: - white grader_notes: type: - string - 'null' description: 'Free-text notes printed on the slab label. Must not be greater than 2000 characters.' examples: - 'Marvel Value Stamp #16 intact' print_number: type: - string - 'null' description: 'Which print this copy is (1st, 2nd, 3rd, … or other).' enum: - 1st - 2nd - 3rd - 4th - 5th - 6th - 7th - 8th - 9th - 10th - other examples: - 1st signature_witness: type: - string - 'null' description: 'Authentication of the signature (CGC, CBCS, JSA, PSA/DNA, witnessed_in_person, unwitnessed, other).' enum: - CGC - CBCS - JSA - PSA/DNA - witnessed_in_person - unwitnessed - other examples: - witnessed_in_person estimated_value: type: - number - 'null' description: 'Current estimated value in dollars. Must be at least 0. Must not be greater than 999999.99.' examples: - 25.0 for_sale: type: boolean description: 'Whether the item is for sale.' examples: - false for_trade: type: boolean description: 'Whether the item is available for trade.' examples: - false is_public: type: boolean description: 'Whether this collection item is publicly visible.' examples: - true is_read: type: boolean description: 'Whether the issue has been read.' examples: - true read_at: type: - string - 'null' description: 'When the issue was read (YYYY-MM-DD). Cannot be in the future. Must be a valid date. Must be a date before or equal to today.' examples: - '2024-06-15' delete: summary: 'Remove issue from collection.' operationId: removeIssueFromCollection description: "Removes an issue (optionally a specific variant) from the user's collection." parameters: - in: query name: variant_id description: 'Specific variant ID to remove (optional).' required: false schema: type: integer description: 'Specific variant ID to remove (optional).' examples: - 789 - in: query name: collection_item_id description: 'Specific collection item ID to remove (optional).' required: false schema: type: integer description: 'Specific collection item ID to remove (optional).' examples: - 1001 responses: '204': description: Success headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: error: type: string examples: - 'Issue not found in your collection.' examples: - error: 'Issue not found in your collection.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: variant_id: type: - integer - 'null' description: 'Specific variant ID to remove (optional).' examples: - 789 collection_item_id: type: - integer - 'null' description: 'Specific collection item ID to remove (optional).' examples: - 1001 parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 /api/v1/user/pull-list: get: summary: 'List pull list.' operationId: listPullList description: "Returns all series on the user's pull list (series they're tracking for new releases)." parameters: - in: query name: per_page description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 123 series: type: object properties: id: type: integer examples: - 456 name: type: string examples: - 'Amazing Spider-Man' publisher: type: object properties: id: type: integer examples: - 1 name: type: string examples: - Marvel cover_url: type: string examples: - ... added_at: type: string examples: - '2024-01-15T10:30:00Z' examples: - - id: 123 series: id: 456 name: 'Amazing Spider-Man' publisher: id: 1 name: Marvel cover_url: ... added_at: '2024-01-15T10:30:00Z' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 2 per_page: type: integer examples: - 20 total: type: integer examples: - 35 examples: - data: - id: 123 series: id: 456 name: 'Amazing Spider-Man' publisher: id: 1 name: Marvel cover_url: ... added_at: '2024-01-15T10:30:00Z' meta: current_page: 1 last_page: 2 per_page: 20 total: 35 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User /api/v1/pull-list/items: post: summary: 'Add to pull list.' operationId: addToPullList description: "Adds a series to the user's pull list to track new releases." parameters: [] responses: '201': description: Success content: application/json: schema: type: object properties: {} examples: - {} headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '422': description: 'Series Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'The selected series id is invalid.' errors: type: object properties: series_id: type: array items: type: string examples: - - 'The selected series id is invalid.' examples: - message: 'The selected series id is invalid.' errors: series_id: - 'The selected series id is invalid.' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: true content: application/json: schema: type: object properties: series_id: type: integer description: 'The series ID to add.' examples: - 456 required: - series_id '/api/v1/pull-list/items/{item_id}': delete: summary: 'Remove from pull list.' operationId: removeFromPullList description: "Removes a series from the authenticated user's pull list." parameters: [] responses: '204': description: Removed headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User parameters: - in: path name: item_id description: 'The series ID of the pull list entry.' required: true schema: type: integer examples: - 456 /api/v1/user/read-status: get: summary: 'List read status.' operationId: listReadStatus description: 'Returns all issues the user has marked as read with timestamps.' parameters: - in: query name: per_page description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 - in: query name: unreviewed description: 'When true, only returns reads for issues the user has not yet reviewed.' required: false schema: type: boolean description: 'When true, only returns reads for issues the user has not yet reviewed.' examples: - true responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 1234 issue: type: object properties: id: type: integer examples: - 5432 number: type: string examples: - '1' title: type: string examples: - 'First Issue' series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' variant_id: type: - string - 'null' examples: - null read_at: type: string examples: - '2024-01-15T10:30:00Z' examples: - - id: 1234 issue: id: 5432 number: '1' title: 'First Issue' series: id: 123 name: 'Amazing Spider-Man' variant_id: null read_at: '2024-01-15T10:30:00Z' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 10 per_page: type: integer examples: - 20 total: type: integer examples: - 200 examples: - data: - id: 1234 issue: id: 5432 number: '1' title: 'First Issue' series: id: 123 name: 'Amazing Spider-Man' variant_id: null read_at: '2024-01-15T10:30:00Z' meta: current_page: 1 last_page: 10 per_page: 20 total: 200 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User '/api/v1/issues/{issue_id}/read-status': post: summary: 'Mark as read.' operationId: markAsRead description: 'Marks an issue (optionally a specific variant) as read with the current timestamp.' parameters: [] responses: '201': description: Success content: application/json: schema: type: object properties: {} examples: - {} headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '422': description: 'Invalid Variant' content: application/json: schema: type: object properties: error: type: string examples: - 'Variant does not belong to this issue' examples: - error: 'Variant does not belong to this issue' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: variant_id: type: - integer - 'null' description: 'Specific variant ID (optional).' examples: - 789 patch: summary: 'Edit reading date.' operationId: editReadingDate description: "Updates the `read_at` date on an existing read entry, or removes the entry when `read_at` is null.\nIf no entry exists yet and a date is provided, one is created (upsert)." parameters: [] responses: '200': description: Updated content: application/json: schema: type: object properties: read_at: type: string examples: - '2026-03-01T00:00:00+00:00' examples: - read_at: '2026-03-01T00:00:00+00:00' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '204': description: 'Cleared (read_at was null)' headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: read_at: type: - string - 'null' description: 'Date in YYYY-MM-DD format, must not be in the future. Pass null to mark as unread.' examples: - '2026-03-01' variant_id: type: - integer - 'null' description: 'Specific variant ID (optional).' examples: - 789 delete: summary: 'Mark as unread.' operationId: markAsUnread description: 'Removes the read status for an issue (optionally a specific variant).' parameters: [] responses: '204': description: Success headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: variant_id: type: - integer - 'null' description: 'Specific variant ID (optional).' examples: - 789 parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 /api/v1/user/wishlist: get: summary: 'List wishlist.' operationId: listWishlist description: "Returns the authenticated user's wishlist issues, most recently added first." parameters: - in: query name: per_page description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 9876 position: type: - string - 'null' examples: - null note: type: - string - 'null' examples: - null created_at: type: string examples: - '2024-01-15T10:30:00Z' updated_at: type: string examples: - '2024-01-15T10:30:00Z' variant_id: type: - string - 'null' examples: - null entity_type: type: string examples: - issues entity: type: object properties: id: type: integer examples: - 5432 name: type: string examples: - 'Amazing Spider-Man #1' issue_number: type: string examples: - '1' image_url: type: string examples: - ... publisher: type: string examples: - Marvel series: type: object properties: id: type: integer examples: - 123 name: type: string examples: - 'Amazing Spider-Man' start_year: type: integer examples: - 2018 examples: - - id: 9876 position: null note: null created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' variant_id: null entity_type: issues entity: id: 5432 name: 'Amazing Spider-Man #1' issue_number: '1' image_url: ... publisher: Marvel series: id: 123 name: 'Amazing Spider-Man' start_year: 2018 meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 4 examples: - data: - id: 9876 position: null note: null created_at: '2024-01-15T10:30:00Z' updated_at: '2024-01-15T10:30:00Z' variant_id: null entity_type: issues entity: id: 5432 name: 'Amazing Spider-Man #1' issue_number: '1' image_url: ... publisher: Marvel series: id: 123 name: 'Amazing Spider-Man' start_year: 2018 meta: current_page: 1 last_page: 1 per_page: 20 total: 4 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User '/api/v1/issues/{issue_id}/wishlist': post: summary: 'Add to wishlist.' operationId: addToWishlist description: "Adds the issue to the authenticated user's wishlist. Idempotent: calling\nwith an issue already on the wishlist returns 200 without creating a duplicate." parameters: [] responses: '200': description: 'Already in Wishlist' content: application/json: schema: type: object properties: in_wishlist: type: boolean examples: - true variant_id: type: integer examples: - 7 examples: - in_wishlist: true variant_id: 7 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '201': description: Added content: application/json: schema: type: object properties: in_wishlist: type: boolean examples: - true variant_id: type: integer examples: - 7 examples: - in_wishlist: true variant_id: 7 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '422': description: 'Wishlist Full' content: application/json: schema: type: object properties: message: type: string examples: - 'Wishlist is full (max 500 items).' examples: - message: 'Wishlist is full (max 500 items).' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: variant_id: type: - integer - 'null' description: 'Optional cover variant to pin. Must belong to the issue. Omit for "any cover". The same issue may sit on the wishlist once per distinct variant plus once variant-less.' examples: - 7 delete: summary: 'Remove from wishlist.' operationId: removeFromWishlist description: "Removes the issue from the authenticated user's wishlist. Idempotent:\nreturns 204 whether or not the issue was on the wishlist." parameters: - in: query name: variant_id description: 'Optional cover variant to remove. Omit to remove the "any cover" entry — variant-pinned entries for the same issue are left alone.' required: false schema: type: integer description: 'Optional cover variant to remove. Omit to remove the "any cover" entry — variant-pinned entries for the same issue are left alone.' examples: - 7 responses: '204': description: Removed headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: false content: application/json: schema: type: object properties: variant_id: type: - integer - 'null' description: 'Optional cover variant of the issue. Must belong to the issue. Omit for "any cover" — the base entry, which is what the app''s quick-add heart writes. Must match an existing stored value.' examples: - 7 parameters: - in: path name: issue_id description: 'The issue ID.' required: true schema: type: integer examples: - 5432 /api/v1/user/follows: get: summary: 'List follows.' operationId: listFollows description: 'Returns all entities the user is following (titles, characters, podcasts, etc.).' parameters: - in: query name: per_page description: 'Items per page (max 100).' required: false schema: type: integer description: 'Items per page (max 100).' examples: - 20 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: integer examples: - 789 followable_type: type: string examples: - title followable_id: type: integer examples: - 123 followable: type: object properties: id: type: integer examples: - 123 name: type: string examples: - Spider-Man cover_url: type: string examples: - ... created_at: type: string examples: - '2024-01-15T10:30:00Z' examples: - - id: 789 followable_type: title followable_id: 123 followable: id: 123 name: Spider-Man cover_url: ... created_at: '2024-01-15T10:30:00Z' meta: type: object properties: current_page: type: integer examples: - 1 last_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 12 examples: - data: - id: 789 followable_type: title followable_id: 123 followable: id: 123 name: Spider-Man cover_url: ... created_at: '2024-01-15T10:30:00Z' meta: current_page: 1 last_page: 1 per_page: 20 total: 12 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User '/api/v1/follow/{type}/{id}/check': get: summary: 'Check follow status.' operationId: checkFollowStatus description: 'Reports whether the authenticated user currently follows the given entity.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: is_following: type: boolean examples: - true examples: - is_following: true headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User parameters: - in: path name: type description: 'The content type (title, character, podcast, creator, publisher, team, story_arc, comic_shop, event, event_franchise, user).' required: true schema: type: string examples: - title - in: path name: id description: 'The ID of the content.' required: true schema: type: integer examples: - 45 /api/v1/follow: post: summary: 'Follow content.' operationId: followContent description: 'Follows a title, character, podcast, creator, publisher, team, story arc, comic shop, event, event franchise, or user.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: message: type: string examples: - 'Following title successfully' is_following: type: boolean examples: - true examples: - message: 'Following title successfully' is_following: true headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Title not found' examples: - message: 'Title not found' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User requestBody: required: true content: application/json: schema: type: object properties: type: type: string description: 'The content type (title, character, podcast, creator, publisher, team, story_arc, comic_shop, event, event_franchise, user). An event_franchise is the recurring convention itself, so the follow covers every future edition.' examples: - title id: type: integer description: 'The ID of the content to follow.' examples: - 45 preferences: type: - object - 'null' description: 'Notification preferences.' properties: email_notifications: type: boolean description: 'Receive email notifications.' examples: - true push_notifications: type: boolean description: 'Receive push notifications.' examples: - false examples: - email_notifications: true push_notifications: false required: - type - id '/api/v1/follow/{type}/{id}': delete: summary: 'Unfollow content.' operationId: unfollowContent description: 'Stops following the given entity for the authenticated user.' parameters: [] responses: '200': description: Success content: application/json: schema: type: object properties: message: type: string examples: - 'Unfollowed title successfully' is_following: type: boolean examples: - false examples: - message: 'Unfollowed title successfully' is_following: false headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 149 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '404': description: 'Not Found' content: application/json: schema: type: object properties: message: type: string examples: - 'Title not found' examples: - message: 'Title not found' '429': description: 'Rate limit exceeded. This endpoint allows 150/hour (free) or 500/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 150 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User parameters: - in: path name: type description: 'The content type (title, character, podcast, creator, publisher, team, story_arc, comic_shop, event, event_franchise, user).' required: true schema: type: string examples: - title - in: path name: id description: 'The ID of the followed content.' required: true schema: type: integer examples: - 45 /api/v1/user/activity: get: summary: 'Get activity feed.' operationId: getActivityFeed description: 'Aggregates recent activity from collections, reads, follows, and reviews.' parameters: - in: query name: per_page description: 'Number of results per page (max 100).' required: false schema: type: integer description: 'Number of results per page (max 100).' examples: - 20 - in: query name: page description: 'Page of results to return.' required: false schema: type: integer description: 'Page of results to return.' examples: - 1 responses: '200': description: Success content: application/json: schema: type: object properties: data: type: array items: type: object properties: id: type: string examples: - collection_9921 type: type: string examples: - collection action: type: string examples: - added_to_collection created_at: type: string examples: - '2026-06-20T14:32:00+00:00' data: type: object properties: issue_id: type: integer examples: - 5432 issue_name: type: string examples: - 'Amazing Spider-Man #1' series_name: type: string examples: - 'Amazing Spider-Man' series_start_year: type: integer examples: - 2022 cover_url: type: string examples: - 'https://r2.versedb.com/uploads/issues/asm-5432/asm-5432-cover_md.webp' examples: - - id: collection_9921 type: collection action: added_to_collection created_at: '2026-06-20T14:32:00+00:00' data: issue_id: 5432 issue_name: 'Amazing Spider-Man #1' series_name: 'Amazing Spider-Man' series_start_year: 2022 cover_url: 'https://r2.versedb.com/uploads/issues/asm-5432/asm-5432-cover_md.webp' - id: review_312 type: review action: wrote_review created_at: '2026-06-19T09:10:00+00:00' data: review_id: 312 issue_id: 5410 issue_name: 'Batman #135' series_name: Batman series_start_year: 2016 rating: 4.5 content_preview: 'A strong anniversary issue that pays off years of buildup...' cover_url: 'https://r2.versedb.com/uploads/issues/batman-5410/batman-5410-cover_md.webp' meta: type: object properties: current_page: type: integer examples: - 1 per_page: type: integer examples: - 20 total: type: integer examples: - 84 last_page: type: integer examples: - 5 examples: - data: - id: collection_9921 type: collection action: added_to_collection created_at: '2026-06-20T14:32:00+00:00' data: issue_id: 5432 issue_name: 'Amazing Spider-Man #1' series_name: 'Amazing Spider-Man' series_start_year: 2022 cover_url: 'https://r2.versedb.com/uploads/issues/asm-5432/asm-5432-cover_md.webp' - id: review_312 type: review action: wrote_review created_at: '2026-06-19T09:10:00+00:00' data: review_id: 312 issue_id: 5410 issue_name: 'Batman #135' series_name: Batman series_start_year: 2016 rating: 4.5 content_preview: 'A strong anniversary issue that pays off years of buildup...' cover_url: 'https://r2.versedb.com/uploads/issues/batman-5410/batman-5410-cover_md.webp' meta: current_page: 1 per_page: 20 total: 84 last_page: 5 headers: X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 299 '401': description: 'Unauthenticated. The bearer token is missing, invalid, or revoked.' content: application/json: schema: $ref: '#/components/schemas/UnauthorizedError' '429': description: 'Rate limit exceeded. This endpoint allows 300/hour (free) or 1,000/hour (PRO). Wait for the number of seconds in the `Retry-After` header before retrying.' headers: Retry-After: description: 'Seconds to wait before retrying.' schema: type: integer examples: - 3600 X-RateLimit-Limit: description: 'Request quota per hour for your tier.' schema: type: integer examples: - 300 X-RateLimit-Remaining: description: 'Requests remaining in the current window.' schema: type: integer examples: - 0 content: application/json: schema: $ref: '#/components/schemas/TooManyRequestsError' tags: - User deprecated: true