Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/cuvo-co:cuvo-co-content-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Cuvo Health public Content API
version: '2026-08-23'
summary: Read-only content, discovery, and $0 discovery-call booking endpoints for AI agents. No authentication, no API keys.
description: 'The public machine interface of cuvo.co, the Cuvo Health white label telehealth platform. Every endpoint is unauthenticated and free; all content mirrors claims already published on the human-readable pages. Human documentation lives at https://cuvo.co/developers (developer portal) and https://cuvo.co/api-docs (endpoint reference).
Versioning: date-based. This document describes version 2026-08-23, echoed on every response in the API-Version header; requests may pin a version by sending the API-Version request header. Breaking changes ship as a new version date, the prior version keeps working for at least 90 days, and responses on a deprecated version carry Deprecation and Sunset headers for that whole window.
Errors: unless an operation says otherwise, errors are RFC 9457 application/problem+json with a machine-readable "code" and a "hint" describing the recovery step. The ACP endpoints return the Agentic Commerce Protocol''s own error body (a messages array); the A2A and MCP endpoints return JSON-RPC 2.0 error objects.
Rate limits: 300 requests per 60 seconds per IP on dynamic endpoints, advertised live in the RateLimit response headers; a 429 carries Retry-After. Statically cached endpoints advertise the policy in RateLimit-Policy.
Related non-API resources: the sitemap at /sitemap.xml, the RSS feed at /feed.xml, the Schema Feeds map at /schemamap.xml (schemamap directive in robots.txt), scoped llms.txt files (/developers/llms.txt, /blog/llms.txt, /compare/llms.txt, /pricing/llms.txt, /api/llms.txt, /docs/llms.txt), and plain-markdown mirrors of the content pages: /index.md for the homepage, and .md appended to /pricing, /developers, /about, /booking, /terms, /privacy, /security, any /blog/, or any /compare/ URL. Every mirror opens with YAML frontmatter (title, description, canonical, last-updated).'
contact:
name: Cuvo Health team
url: https://cuvo.co/booking
termsOfService: https://cuvo.co/terms
license:
name: Proprietary (free to call; content mirrors the published site)
url: https://cuvo.co/terms
servers:
- url: https://cuvo.co
security: []
tags:
- name: Content
description: Published site content for agents
paths:
/llms.txt:
parameters:
- $ref: '#/components/parameters/ApiVersion'
get:
operationId: getLlmsTxt
tags:
- Content
summary: Site summary for AI assistants
description: 'Markdown summary of Cuvo (llmstxt.org format): what the platform runs, published pricing, key facts, canonical Q&As, and when-to-use guidance for agents.'
responses:
'200':
description: OK
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
content:
text/plain:
schema:
type: string
description: Markdown document
4XX:
$ref: '#/components/responses/FallbackNotFound'
/llms-full.txt:
parameters:
- $ref: '#/components/parameters/ApiVersion'
get:
operationId: getLlmsFullText
tags:
- Content
summary: Full published content
description: Complete text of every published article and comparison page in one markdown document.
responses:
'200':
description: OK
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
content:
text/plain:
schema:
type: string
description: Markdown document
4XX:
$ref: '#/components/responses/FallbackNotFound'
/compare/{slug}.md:
parameters:
- $ref: '#/components/parameters/ApiVersion'
get:
operationId: getComparisonMarkdown
tags:
- Content
summary: Markdown mirror of a comparison page
description: Plain-markdown mirror of a /compare/{slug} page. Append .md to any comparison page URL. Unknown slugs return a markdown 404 with recovery links.
parameters:
- name: slug
in: path
required: true
description: Comparison page slug.
schema:
type: string
enum:
- cuvo-vs-wheel
- cuvo-vs-steadymd
- cuvo-vs-beluga-health
- cuvo-vs-telegra
- cuvo-vs-carevalidate
- cuvo-vs-qualiphy
- cuvo-vs-rimo
- cuvo-vs-fuse-health
- cuvo-vs-karpa
- cuvo-vs-lyv-care
- cuvo-vs-nimbusrx
- cuvo-vs-ola-digital-health
- cuvo-vs-openloop
- cuvo-vs-bask-health
- cuvo-vs-remedora
- cuvo-vs-therxspot
- cuvo-vs-wellsync
- cuvo-vs-white-label-md
- cuvo-vs-wizlo
responses:
'200':
description: OK
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
content:
text/markdown:
schema:
type: string
description: Markdown document
'404':
description: Unknown slug. Markdown body listing where to look next.
content:
text/markdown:
schema:
type: string
description: Markdown document
/ask:
parameters:
- $ref: '#/components/parameters/ApiVersion'
get:
operationId: ask
tags:
- Content
summary: Natural-language query (NLWeb)
description: 'NLWeb /ask endpoint: pass a natural-language question as ?query= and get ranked links into the published pages, articles, and comparisons, answered deterministically from published content. Add ?streaming=true (or Accept: text/event-stream) for SSE with NLWeb event types start/result/complete.'
parameters:
- name: query
in: query
required: true
description: The natural-language question.
schema:
type: string
- name: streaming
in: query
required: false
description: true switches the response to SSE.
schema:
type: boolean
responses:
'200':
description: Ranked results (JSON by default; text/event-stream when streaming).
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimitLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimitRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/AskResponse'
text/event-stream:
schema:
type: string
description: 'SSE stream with NLWeb event types: start, result (one per item), complete.'
'400':
description: Missing query (problem+json, code missing_query).
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/Problem'
post:
operationId: askPost
tags:
- Content
summary: Natural-language query (NLWeb, POST)
description: 'POST body form of /ask: {"query": "..."} with optional {"prefer": {"streaming": true}} for SSE.'
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
query:
type: string
prefer:
type: object
properties:
streaming:
type: boolean
required:
- query
responses:
'200':
description: Ranked results (JSON by default; text/event-stream when prefer.streaming).
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimitLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimitRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimitReset'
content:
application/json:
schema:
$ref: '#/components/schemas/AskResponse'
text/event-stream:
schema:
type: string
description: 'SSE stream with NLWeb event types: start, result (one per item), complete.'
'400':
description: Missing query (problem+json, code missing_query).
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/Problem'
/api/articles:
parameters:
- $ref: '#/components/parameters/ApiVersion'
get:
operationId: listArticles
tags:
- Content
summary: List published articles (paginated)
description: 'The published blog articles as a typed JSON list with cursor pagination: pass limit (1-50, default 20) and follow next_cursor until it is null. Each item links the HTML page and its markdown mirror.'
parameters:
- $ref: '#/components/parameters/PageLimit'
- $ref: '#/components/parameters/PageCursor'
responses:
'200':
description: One page of results.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimitLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimitRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimitReset'
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/ArticleListItem'
next_cursor:
type:
- string
- 'null'
description: Opaque cursor for the next page; null on the last page. Pass back as ?cursor=.
total:
type: integer
required:
- items
- next_cursor
- total
'400':
description: Invalid limit or cursor (problem+json with code invalid_limit or invalid_cursor).
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/Problem'
/api/comparisons:
parameters:
- $ref: '#/components/parameters/ApiVersion'
get:
operationId: listComparisons
tags:
- Content
summary: List comparison pages (paginated)
description: The Cuvo-vs-competitor comparison pages as a typed JSON list, same cursor pagination shape as /api/articles.
parameters:
- $ref: '#/components/parameters/PageLimit'
- $ref: '#/components/parameters/PageCursor'
responses:
'200':
description: One page of results.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimitLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimitRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimitReset'
content:
application/json:
schema:
type: object
properties:
items:
type: array
items:
$ref: '#/components/schemas/ComparisonListItem'
next_cursor:
type:
- string
- 'null'
description: Opaque cursor for the next page; null on the last page. Pass back as ?cursor=.
total:
type: integer
required:
- items
- next_cursor
- total
'400':
description: Invalid limit or cursor (problem+json with code invalid_limit or invalid_cursor).
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
'429':
$ref: '#/components/responses/RateLimited'
default:
$ref: '#/components/responses/Problem'
components:
headers:
RateLimitLimit:
description: Requests allowed per window (draft-07 form).
schema:
type: integer
RateLimitPolicy:
description: Rate-limit policy (draft-ietf-httpapi-ratelimit-headers structured field), e.g. "default";q=60;w=60.
schema:
type: string
RateLimit:
description: 'Live quota state: "default";r=<remaining>;t=<seconds to reset>.'
schema:
type: string
ApiVersion:
description: The API version that served this response.
schema:
type: string
enum:
- '2026-08-23'
RateLimitRemaining:
description: Requests remaining in the current window.
schema:
type: integer
RateLimitReset:
description: Seconds until the current window resets.
schema:
type: integer
schemas:
ArticleListItem:
type: object
description: One published blog article in the paginated list.
properties:
slug:
type: string
title:
type: string
excerpt:
type: string
date:
type: string
category:
type: string
url:
type: string
format: uri
markdown_url:
type: string
format: uri
required:
- slug
- title
- excerpt
- date
- url
- markdown_url
AskResponse:
type: object
description: 'NLWeb response: ranked links answered deterministically from published content.'
properties:
_meta:
type: object
properties:
response_type:
type: string
enum:
- list
version:
type: string
required:
- response_type
- version
query_id:
type: string
query:
type: string
results:
type: array
items:
type: object
properties:
url:
type: string
format: uri
name:
type: string
site:
type: string
score:
type: number
description:
type: string
schema_object:
type: object
required:
- url
- name
- site
- score
- description
required:
- _meta
- query_id
- query
- results
ComparisonListItem:
type: object
description: One comparison page in the paginated list.
properties:
slug:
type: string
competitor:
type: string
summary:
type: string
facts_reviewed:
type: string
url:
type: string
format: uri
markdown_url:
type: string
format: uri
required:
- slug
- competitor
- summary
- url
- markdown_url
Problem:
type: object
description: RFC 9457 problem detail. code is stable and machine-readable; hint says what to do next. Documented at https://cuvo.co/developers#errors
properties:
type:
type: string
format: uri
title:
type: string
status:
type: integer
detail:
type: string
code:
type: string
description: Machine-readable error code (snake_case), e.g. not_found, method_not_allowed, rate_limited.
hint:
type: string
description: Suggested next step for the caller.
instance:
type: string
required:
- title
- status
- detail
- code
responses:
FallbackNotFound:
description: 'Any client error at a statically served URL falls through to the site-wide fallback: a real 4xx status whose body is short markdown with recovery links (sitemap, llms.txt, developer portal) for clients that do not ask for HTML.'
content:
text/markdown:
schema:
type: string
description: Markdown document
Problem:
description: Error (RFC 9457 problem detail with machine-readable code and recovery hint).
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
RateLimited:
description: Rate limit exceeded. Wait Retry-After seconds, then retry.
headers:
API-Version:
$ref: '#/components/headers/ApiVersion'
RateLimit-Policy:
$ref: '#/components/headers/RateLimitPolicy'
RateLimit:
$ref: '#/components/headers/RateLimit'
RateLimit-Limit:
$ref: '#/components/headers/RateLimitLimit'
RateLimit-Remaining:
$ref: '#/components/headers/RateLimitRemaining'
RateLimit-Reset:
$ref: '#/components/headers/RateLimitReset'
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
parameters:
PageCursor:
name: cursor
in: query
required: false
description: Opaque cursor from a previous response's next_cursor; omit for the first page.
schema:
type: string
PageLimit:
name: limit
in: query
required: false
description: Items per page, 1-50 (default 20).
schema:
type: integer
minimum: 1
maximum: 50
default: 20
ApiVersion:
name: API-Version
in: header
required: false
description: Pin a specific API version (date-based). Omitting it selects the current version; every response echoes the version served.
schema:
type: string
enum:
- '2026-08-23'