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/cavuno-com:cavuno-com-subscribers-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: Cavuno v1 REST Subscribers API
version: 1.0.0
description: 'The Cavuno API is organized around REST. Our API has predictable resource-oriented URLs, accepts JSON-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs. ## Base URL
Production: `https://api.cavuno.com/v1`
All API requests must be made over HTTPS. Calls made over plain HTTP will fail. ## Authentication
The Cavuno API uses API keys to authenticate requests. You can view and manage your API keys in the Cavuno dashboard, under Settings → Developer → API keys. Cavuno API keys have the prefix `cavuno_live_`. Your API keys carry many privileges, so be sure to keep them secure. Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth. Authentication to the API is performed via Bearer auth. Provide your API key as the bearer token in the `Authorization` header:
```bash
curl https://api.cavuno.com/v1/jobs \
-H "Authorization: Bearer YOUR_SECRET_API_KEY"
```
API requests without authentication will fail. ## Rate limits
The Cavuno API has rate limits in place to ensure stability and reliability. By default, API keys are limited to 100 requests per minute. If you exceed your limit, requests return an HTTP 429 response with a `Retry-After` header indicating when you can try again. If you have a use case that needs a higher limit, contact support. ## Idempotency
The API supports idempotency for safely retrying requests without accidentally performing the same operation twice. For example, if a request to create a job fails due to a network connection error, you can safely retry the request with the same idempotency key, and we''ll guarantee that only one job is created. To perform an idempotent request, provide an additional `Idempotency-Key` header on any `POST`, `PATCH`, or `DELETE` request:
```bash
curl https://api.cavuno.com/v1/jobs \
-X POST \
-H "Authorization: Bearer cavuno_live_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d ''{ "title": "Senior Engineer" }''
```
## Errors
Cavuno uses conventional HTTP response codes to indicate the success or failure of an API request. In general: codes in the `2xx` range indicate success, codes in the `4xx` range indicate an error that failed given the information provided (e.g., a required parameter was omitted), and codes in the `5xx` range indicate an error with Cavuno''s servers (these are rare). Error responses include a JSON body with details:
```json
{
"error": {
"code": "validation_bad_request",
"message": "Field ''title'' is required.",
"requestId": "req_..."
}
}
```
Some errors carry an additional `details` field with structured context, such as per-field validation issues. ### Plan upgrade hints
When an Operator API request is refused because of the board''s Cavuno plan, the error also carries an `upgrade` object. It names the capability that blocked the request, the cheapest self-serve plan that unlocks it (when that can be told), and the hosted billing endpoints that start the upgrade:
```json
{
"error": {
"code": "settings_plan_required_for_branding_removal",
"message": "Removing Cavuno branding requires a plan that includes branding removal.",
"requestId": "req_...",
"upgrade": {
"capability": "canRemoveBranding",
"requiredPlan": "basic",
"checkout": { "method": "POST", "path": "/v1/billing/checkout" },
"changePlan": { "method": "POST", "path": "/v1/billing/upgrade" }
}
}
}
```
Call `GET /v1/billing/subscription` first. With no active subscription, use `checkout`; with one, use `changePlan`. Send `{ "planKey": "" }` and give the returned `url` to a person: both endpoints return a hosted page where a person confirms the purchase. Nothing is charged until they do. Each `path` is relative to the API origin (`https://api.cavuno.com`), like `Location` headers and list `url` fields, so do not join it to a base URL that already ends in `/v1`.'
contact:
name: Cavuno
url: https://cavuno.com
servers:
- url: https://api.cavuno.com/v1
description: Production
security:
- bearerAuth: []
tags:
- name: Subscribers
description: 'Job-alert subscribers: list, export, un/resubscribe, and import.'
paths:
/subscribers:
get:
summary: List subscribers
description: Returns the subscribers of the authenticated account. Alerts are not inlined here. Fetch them via `GET /v1/subscribers/{id}/alerts`. Requires `alerts.read`.
parameters:
- schema:
type: string
minLength: 1
description: Pagination cursor.
required: false
description: Pagination cursor.
name: cursor
in: query
- schema:
type: integer
minimum: 1
maximum: 100
description: Page size (1–100, default 50).
required: false
description: Page size (1–100, default 50).
name: limit
in: query
- schema:
type: string
minLength: 1
description: Case-insensitive substring match on the subscriber email.
required: false
description: Case-insensitive substring match on the subscriber email.
name: search
in: query
- schema:
type: string
enum:
- confirmed
- unconfirmed
- unsubscribed
- waitlisted
description: Filter subscribers by lifecycle status.
required: false
description: Filter subscribers by lifecycle status.
name: status
in: query
responses:
'200':
description: Successful response.
content:
application/json:
schema:
type: object
properties:
object:
type: string
enum:
- list
url:
type: string
example: /v1/subscribers
hasMore:
type: boolean
nextCursor:
type:
- string
- 'null'
data:
type: array
items:
$ref: '#/components/schemas/Subscriber'
required:
- object
- url
- hasMore
- nextCursor
- data
default:
description: An error. Every non-2xx response uses the same envelope; see the Errors section of the introduction.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: listSubscribers
/subscribers/{id}:
get:
summary: Retrieve a subscriber
description: Fetches a single subscriber with their alerts inline. Requires `alerts.read`.
parameters:
- schema:
type: string
minLength: 1
description: The subscriber ID.
required: true
description: The subscriber ID.
name: id
in: path
responses:
'200':
description: Successful response.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberDetail'
'404':
description: Subscriber not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: getSubscriber
/subscribers/count:
get:
summary: Count confirmed subscribers
description: 'Returns the count of confirmed subscribers for the account. Cheap and cacheable. Requires `alerts.read`. Note: this counts every subscriber that has ever confirmed and is not decremented on unsubscribe, so it can exceed the size of `GET /v1/subscribers?status=confirmed` (which additionally excludes unsubscribed rows).'
responses:
'200':
description: Successful response.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberCount'
default:
description: An error. Every non-2xx response uses the same envelope; see the Errors section of the introduction.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: countSubscribers
/subscribers/{id}/alerts:
get:
summary: List a subscriber’s alerts
description: Returns the alerts belonging to a specific subscriber. Requires `alerts.read`.
parameters:
- schema:
type: string
minLength: 1
description: The subscriber ID.
required: true
description: The subscriber ID.
name: id
in: path
responses:
'200':
description: Successful response.
content:
application/json:
schema:
type: object
properties:
object:
type: string
enum:
- list
url:
type: string
example: /v1/subscribers/subscribers_k1000abc/alerts
hasMore:
type: boolean
nextCursor:
type:
- string
- 'null'
data:
type: array
items:
$ref: '#/components/schemas/SubscriberAlert'
required:
- object
- url
- hasMore
- nextCursor
- data
'404':
description: Subscriber not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: listSubscriberAlerts
/subscribers/{id}/unsubscribe:
post:
summary: Unsubscribe a subscriber
description: 'Admin-initiated unsubscribe: sets `unsubscribedAt` and deactivates the subscriber’s alerts. Requires `alerts.manage`.'
parameters:
- schema:
type: string
minLength: 1
description: The subscriber ID.
required: true
description: The subscriber ID.
name: id
in: path
responses:
'200':
description: Successful response.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberDetail'
'404':
description: Subscriber not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: The subscriber is already unsubscribed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: unsubscribeSubscriber
/subscribers/{id}/resubscribe:
post:
summary: Resubscribe a subscriber
description: 'Admin-initiated resubscribe: clears `unsubscribedAt` and reactivates the subscriber’s alerts after email confirmation. Requires `alerts.manage`.'
parameters:
- schema:
type: string
minLength: 1
description: The subscriber ID.
required: true
description: The subscriber ID.
name: id
in: path
responses:
'200':
description: Successful response.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberDetail'
'404':
description: Subscriber not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: The subscriber is not currently unsubscribed or has not confirmed their email.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: resubscribeSubscriber
/subscribers/{id}/resend-confirmation:
post:
summary: Resend a confirmation email
description: Emails a fresh confirmation link to a subscriber who has not confirmed their email yet. You can send one every two minutes per subscriber. Requires `alerts.manage`.
parameters:
- schema:
type: string
minLength: 1
description: The subscriber ID.
required: true
description: The subscriber ID.
name: id
in: path
responses:
'200':
description: The confirmation email was sent.
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberDetail'
'404':
description: Subscriber not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: The subscriber has already confirmed (`subscribers_already_confirmed`) or is unsubscribed (`subscribers_already_unsubscribed`).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: A confirmation email was sent to this subscriber in the last two minutes (`subscribers_confirmation_throttled`). Retry after the `Retry-After` header.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'502':
description: The email could not be sent (`subscribers_confirmation_send_failed`). Retry after two minutes.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: resendSubscriberConfirmation
/subscribers/export:
get:
summary: Export subscribers
description: Exports the account’s subscribers. `format=json` returns an inline list (max 10,000 rows). `format=csv` (default) returns `202` with an operation. Poll it, then download the CSV from `GET /v1/operations/{id}/download` once it succeeds. Requires `alerts.read`.
parameters:
- schema:
type: string
enum:
- csv
- json
default: csv
description: Export format. `json` streams an inline list (capped at 10,000 rows); `csv` starts an async `subscribers.export` operation whose CSV is downloadable from `GET /v1/operations/{id}/download` once it succeeds.
required: false
description: Export format. `json` streams an inline list (capped at 10,000 rows); `csv` starts an async `subscribers.export` operation whose CSV is downloadable from `GET /v1/operations/{id}/download` once it succeeds.
name: format
in: query
responses:
'200':
description: Inline JSON export (`format=json`).
content:
application/json:
schema:
type: object
properties:
object:
type: string
enum:
- list
url:
type: string
example: /v1/subscribers/export
hasMore:
type: boolean
nextCursor:
type:
- string
- 'null'
data:
type: array
items:
$ref: '#/components/schemas/Subscriber'
required:
- object
- url
- hasMore
- nextCursor
- data
'202':
description: A `subscribers.export` operation was started (`format=csv`). Poll the operation; once it succeeds, download the CSV from `GET /v1/operations/{id}/download`.
content:
application/json:
schema:
$ref: '#/components/schemas/OperationResource'
default:
description: An error. Every non-2xx response uses the same envelope; see the Errors section of the introduction.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: exportSubscribers
/subscribers/import:
post:
summary: Import subscribers
description: Bulk-imports subscribers from a CSV upload (`multipart/form-data`, field `file`; 10MB / 50,000-row max). `sendConfirmation` defaults to `true`. Returns `202` with a `subscribers.import` operation. Poll it; the terminal result is `{ totalRows, created, skippedDuplicates, failed, errors[] }`. Imported subscribers remain unconfirmed and do not receive active alerts until they complete opt-in. Requires `alerts.manage`.
requestBody:
required: true
content:
multipart/form-data:
schema:
type: object
properties:
file:
type: string
format: binary
description: The CSV file (header row with an `email` column).
sendConfirmation:
type: boolean
default: true
description: Whether to send a double-opt-in confirmation email to imported unconfirmed subscribers.
required:
- file
responses:
'202':
description: A `subscribers.import` operation was started. Poll it for the terminal import summary.
content:
application/json:
schema:
$ref: '#/components/schemas/OperationResource'
'400':
description: Unsupported file format (CSV only).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'413':
description: The import file exceeds the size limit.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Subscribers
operationId: importSubscribers
components:
schemas:
OperationErrorEnvelope:
type:
- object
- 'null'
properties:
code:
type: string
description: Machine-readable error code.
message:
type: string
description: Human-readable error message.
required:
- code
- message
description: Error envelope, populated once the operation reaches `failed`. `null` otherwise.
Subscriber:
type: object
properties:
id:
type: string
description: Unique identifier for the subscriber.
object:
type: string
enum:
- subscriber
description: String representing the object's type.
email:
type: string
description: The subscriber's email address.
confirmedAt:
type:
- string
- 'null'
description: ISO-8601 timestamp of double-opt-in confirmation, or `null`.
waitlistedAt:
type:
- string
- 'null'
description: ISO-8601 timestamp of when the subscriber was waitlisted.
unsubscribedAt:
type:
- string
- 'null'
description: ISO-8601 timestamp of when the subscriber unsubscribed.
createdAt:
type: string
description: ISO-8601 timestamp of when the subscriber was created.
required:
- id
- object
- email
- confirmedAt
- waitlistedAt
- unsubscribedAt
- createdAt
SubscriberDetail:
allOf:
- $ref: '#/components/schemas/Subscriber'
- type: object
properties:
lastSentAt:
type:
- string
- 'null'
description: ISO-8601 timestamp of the most recent alert dispatch, or `null`.
alerts:
type: array
items:
$ref: '#/components/schemas/SubscriberAlert'
description: The subscriber's alerts.
required:
- lastSentAt
- alerts
SubscriberAlert:
type: object
properties:
id:
type: string
description: Unique identifier for the alert.
object:
type: string
enum:
- alert
description: String representing the object's type.
subscriberId:
type: string
description: Identifier of the subscriber that owns this alert.
filters:
description: The job-filter criteria the alert matches against.
frequency:
type: string
enum:
- weekly
description: Weekly delivery cadence.
isActive:
type: boolean
description: Whether the alert is currently active.
lastSentAt:
type:
- string
- 'null'
description: ISO-8601 timestamp of the last dispatch, or `null`.
createdAt:
type: string
description: ISO-8601 timestamp of when the alert was created.
required:
- id
- object
- subscriberId
- frequency
- isActive
- lastSentAt
- createdAt
SubscriberCount:
type: object
properties:
object:
type: string
enum:
- subscriber_count
confirmed:
type: number
description: The number of confirmed subscribers for the account.
required:
- object
- confirmed
OperationProgress:
type:
- object
- 'null'
properties:
percent:
type: number
description: Progress as a percentage between 0 and 100, when the operation reports a percentage.
message:
type: string
description: Human-readable progress message, when available.
processed:
type: number
description: Number of items processed so far, when applicable.
total:
type: number
description: Total number of items to process, when known.
description: Snapshot of the operation's progress, or `null` if the operation does not report progress.
PlanUpgradeHint:
type: object
properties:
capability:
type: string
enum:
- activeJobsLimit
- teamSeatLimit
- canBePublic
- canRemoveBranding
- apiAccess
description: The plan capability that blocked the request, named as in `GET /v1/billing/subscription` `capabilities`.
requiredPlan:
type: string
enum:
- starter
- basic
- grow
- advanced
- scale
description: The cheapest self-serve plan that unlocks the action. Pass it as `planKey`. Omitted when it cannot be told without more information; read `GET /v1/billing/subscription` and pick a higher plan.
checkout:
type: object
properties:
method:
type: string
enum:
- POST
path:
type: string
enum:
- /v1/billing/checkout
required:
- method
- path
description: Starts a hosted checkout when the board has no active subscription (for example during a trial).
changePlan:
type: object
properties:
method:
type: string
enum:
- POST
path:
type: string
enum:
- /v1/billing/upgrade
required:
- method
- path
description: Starts a hosted plan change when the board already has an active subscription.
required:
- capability
- checkout
- changePlan
description: 'Present only on Operator API errors caused by the board''s Cavuno plan. Read `GET /v1/billing/subscription` to choose between `checkout` and `changePlan`, call it with `{ "planKey": requiredPlan }`, and give the returned `url` to a person to confirm. Each `path` is relative to the API origin, not to a `/v1` base URL. Both endpoints need `billing.manage`. Board API errors never include it.'
OperationResource:
type: object
properties:
id:
type: string
description: Unique identifier for the object.
object:
type: string
enum:
- operation
description: String representing the object's type. Objects of the same type share the same value.
kind:
type: string
enum:
- domains.verify
- imports.parse
- imports.confirm
- subscribers.export
- subscribers.import
- custom_objects.records_import
- exports.generate
- candidates.remove
- employers.remove
description: Operation kind, identifying which workflow the operation runs.
state:
type: string
enum:
- pending
- running
- succeeded
- failed
- cancelled
description: Current state of the operation.
progress:
$ref: '#/components/schemas/OperationProgress'
result:
type:
- object
- 'null'
properties:
totalRows:
type: number
created:
type: number
updated:
type: number
failed:
type: number
errors:
type: array
items:
type: object
properties:
rowIndex:
type: number
code:
type: string
message:
type: string
required:
- rowIndex
- code
- message
required:
- totalRows
- created
- updated
- failed
- errors
description: A safe workflow result summary when the operation kind publishes one.
error:
$ref: '#/components/schemas/OperationErrorEnvelope'
createdAt:
type: string
description: Time at which the operation was created. ISO 8601 datetime.
updatedAt:
type: string
description: Time at which the operation was last updated. ISO 8601 datetime.
completedAt:
type:
- string
- 'null'
description: Time at which the operation reached a terminal state, or `null` if it has not yet completed. ISO 8601 datetime.
cancelRequested:
type: boolean
description: Whether cancellation of the operation has been requested.
resource:
type:
- object
- 'null'
properties:
object:
type: string
enum:
- company
- domain
- import
- employer
- candidate
- custom_object_type
id:
type: string
required:
- object
- id
description: Stable product resource affected by the operation, or `null` when no public resource applies.
required:
- id
- object
- kind
- state
- progress
- error
- createdAt
- updatedAt
- completedAt
- cancelRequested
- resource
Error:
type: object
properties:
error:
type: object
properties:
code:
type: string
description: Machine-readable error code, such as `validation_bad_request` or `jobs_not_found`.
message:
type: string
description: Human-readable explanation.
requestId:
type: string
description: Unique id for this request. Include it when contacting support.
details:
description: Structured context for some errors, such as per-field validation issues.
upgrade:
$ref: '#/components/schemas/PlanUpgradeHint'
required:
- code
- message
- requestId
required:
- error
description: The error envelope returned by every non-2xx response.
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: cavuno_live_<keyId>_<secret>
description: Use your secret API key to authenticate. Pass it as a Bearer token in the `Authorization` header. You can view and manage your API keys in the Cavuno dashboard.
externalDocs:
description: Cavuno API reference
url: https://cavuno.com/docs/api