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-webhooks-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 Webhooks 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: Webhooks
description: Configure Board-owned outbound webhook endpoints, inspect delivery history, and replay completed deliveries.
paths:
/webhook-endpoints:
get:
summary: List webhook endpoints
description: Returns Board-owned webhook endpoints. Secrets are never included.
parameters:
- schema:
type: string
minLength: 1
required: false
name: cursor
in: query
- schema:
type: integer
minimum: 1
maximum: 100
required: false
name: limit
in: query
responses:
'200':
description: Successful response.
content:
application/json:
schema:
type: object
properties:
object:
type: string
enum:
- list
url:
type: string
example: /v1/webhook-endpoints
hasMore:
type: boolean
nextCursor:
type:
- string
- 'null'
data:
type: array
items:
$ref: '#/components/schemas/WebhookEndpoint'
required:
- object
- url
- hasMore
- nextCursor
- data
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.read or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: listWebhookEndpoints
post:
summary: Create a webhook endpoint
description: Creates an enabled Board-owned webhook endpoint and returns the signing secret once. The endpoint immediately receives the selected supported V1 event types. The secret is returned only on the original response and is not replayed by an idempotent retry — recover a lost secret by rotating.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateWebhookEndpointBody'
responses:
'201':
description: Endpoint created; secret returned once.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpointCreated'
'400':
description: Invalid URL or event types.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.manage or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: createWebhookEndpoint
/webhook-endpoints/{id}:
get:
summary: Retrieve a webhook endpoint
parameters:
- schema:
type: string
minLength: 1
description: The webhook endpoint ID.
required: true
description: The webhook endpoint ID.
name: id
in: path
responses:
'200':
description: Successful response.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.read or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Endpoint not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: getWebhookEndpoint
patch:
summary: Update a webhook endpoint
description: Updates URL, event selection, or status (pause/resume). URL or event-type changes create a new immutable configuration version.
parameters:
- schema:
type: string
minLength: 1
description: The webhook endpoint ID.
required: true
description: The webhook endpoint ID.
name: id
in: path
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateWebhookEndpointBody'
responses:
'200':
description: Successful response.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpoint'
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.manage or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Endpoint not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: updateWebhookEndpoint
delete:
summary: Retire a webhook endpoint
description: 'Soft-retires the endpoint: future live deliveries stop and open deliveries are cancelled, but immutable configuration, destination, and signing material are retained so existing deliveries can still be inspected and manually replayed within the retention window. Retired endpoints are hidden from list/detail reads.'
parameters:
- schema:
type: string
minLength: 1
description: The webhook endpoint ID.
required: true
description: The webhook endpoint ID.
name: id
in: path
responses:
'204':
description: Retired.
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.manage or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Endpoint not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: deleteWebhookEndpoint
/webhook-endpoints/{id}/rotate-secret:
post:
summary: Rotate a webhook endpoint secret
description: Issues a new signing secret (returned once) and keeps the previous secret verifiable for a bounded overlap window. The secret is returned only on the original response and is not replayed by an idempotent retry — recover a lost secret by rotating.
parameters:
- schema:
type: string
minLength: 1
description: The webhook endpoint ID.
required: true
description: The webhook endpoint ID.
name: id
in: path
responses:
'200':
description: Secret rotated; new secret returned once.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookEndpointCreated'
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.manage or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Endpoint not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: rotateWebhookEndpointSecret
/webhook-endpoints/{id}/test:
post:
summary: Send a synthetic test delivery
description: Sends one unmistakably synthetic signed delivery to the endpoint URL and returns a sanitized outcome. Never copies real domain data.
parameters:
- schema:
type: string
minLength: 1
description: The webhook endpoint ID.
required: true
description: The webhook endpoint ID.
name: id
in: path
responses:
'200':
description: Test delivery attempted.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookTestDelivery'
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.manage or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Endpoint not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: testWebhookEndpoint
/webhook-deliveries:
get:
summary: List webhook deliveries
description: 'Returns Board-scoped delivery history, newest first. Optional filters: endpoint_id, status. Lease identity and raw event bodies are never included.'
parameters:
- schema:
type: string
minLength: 1
required: false
name: cursor
in: query
- schema:
type: integer
minimum: 1
maximum: 100
required: false
name: limit
in: query
- schema:
type: string
minLength: 1
description: Filter to deliveries for a single endpoint.
required: false
description: Filter to deliveries for a single endpoint.
name: endpoint_id
in: query
- schema:
type: string
enum:
- pending
- retrying
- delivered
- terminal
- exhausted
description: Filter by public delivery lifecycle status.
required: false
description: Filter by public delivery 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/webhook-deliveries
hasMore:
type: boolean
nextCursor:
type:
- string
- 'null'
data:
type: array
items:
$ref: '#/components/schemas/WebhookDelivery'
required:
- object
- url
- hasMore
- nextCursor
- data
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.read or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: listWebhookDeliveries
/webhook-deliveries/{id}:
get:
summary: Retrieve a webhook delivery
description: 'Returns a delivery including its most recent attempt history (≤500 attempts, ascending by attempt_number). `attempt_count` is authoritative: when it exceeds `attempts.length`, older attempts were truncated. Never exposes lease fields or serialized event bodies.'
parameters:
- schema:
type: string
minLength: 1
description: The webhook delivery ID.
required: true
description: The webhook delivery ID.
name: id
in: path
responses:
'200':
description: Successful response. `attempts` holds the most recent ≤500 attempts in ascending order; `attempt_count > attempts.length` implies truncation.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookDeliveryDetail'
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.read or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Delivery not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: getWebhookDelivery
/webhook-deliveries/{id}/replay:
post:
summary: Replay a webhook delivery
description: 'Resets a completed delivery (delivered, terminal, or exhausted) so the worker will attempt it again. Reuses the frozen event bytes and the occurrence-time endpoint configuration version; each attempt is signed with a fresh timestamp. Never creates a new domain event. Open deliveries (pending or retrying), deliveries outside the fixed 30-day retention window, and deliveries whose endpoint or frozen config version has been deleted return 409. A replayed exhausted delivery retains its attempt history, so if the replay attempt fails retryably it may exhaust again immediately: replay grants a fresh attempt, not a fresh retry budget.'
parameters:
- schema:
type: string
minLength: 1
description: The webhook delivery ID.
required: true
description: The webhook delivery ID.
name: id
in: path
responses:
'200':
description: Delivery reset to pending for a fresh attempt.
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookDelivery'
'402':
description: The board's plan does not include webhooks (`plan_upgrade_required`). Webhooks require a paid plan, Starter and above.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: Missing webhooks.manage or a family read scope.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Delivery not found.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: 'Cannot replay: delivery is still open, its 30-day replay window expired, or its destination no longer exists.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
x-audience: operator
tags:
- Webhooks
operationId: replayWebhookDelivery
components:
schemas:
CreateWebhookEndpointBody:
type: object
properties:
url:
type: string
maxLength: 2048
format: uri
description: Public HTTPS URL that will receive webhook deliveries.
event_types:
type: array
items:
type: string
enum:
- job.created
- job.updated
- job.deleted
- company.created
- company.updated
- company.deleted
- company.verification.updated
- candidate.created
- candidate.updated
- candidate.deleted
- candidate.profile.updated
- candidate.verification.updated
- marketing_permission.granted
- marketing_permission.withdrawn
- digital_product.purchased
- digital_product.refunded
minItems: 1
description: V1 event types this endpoint subscribes to (unique).
required:
- url
- event_types
additionalProperties: false
WebhookDelivery:
type: object
properties:
id:
type: string
object:
type: string
enum:
- webhook_delivery
event_id:
type: string
description: Stable public event id (e.g. evt_…). Unchanged across retries and replay.
event_type:
type: string
endpoint_id:
type: string
status:
type: string
enum:
- pending
- retrying
- delivered
- terminal
- exhausted
terminal_reason:
type:
- string
- 'null'
enum:
- http_410
- permanent_response
- invalid_reference
- endpoint_paused
- retry_attempt_limit
- delivery_window_expired
- retention_expired
- endpoint_retired
- null
replayable:
type: boolean
replay_expires_at:
type: string
payload_purged_at:
type:
- string
- 'null'
attempt_count:
type: integer
next_attempt_at:
type:
- string
- 'null'
first_attempt_at:
type:
- string
- 'null'
last_attempt_at:
type:
- string
- 'null'
completed_at:
type:
- string
- 'null'
created_at:
type: string
required:
- id
- object
- event_id
- event_type
- endpoint_id
- status
- terminal_reason
- replayable
- replay_expires_at
- payload_purged_at
- attempt_count
- next_attempt_at
- first_attempt_at
- last_attempt_at
- completed_at
- created_at
WebhookTestDelivery:
type: object
properties:
object:
type: string
enum:
- webhook_test_delivery
delivered:
type: boolean
status:
type:
- number
- 'null'
status_class:
type: string
latency_ms:
type: number
diagnostic:
type: string
required:
- object
- delivered
- status
- status_class
- latency_ms
- diagnostic
WebhookDeliveryDetail:
allOf:
- $ref: '#/components/schemas/WebhookDelivery'
- type: object
properties:
attempts:
type: array
items:
$ref: '#/components/schemas/WebhookDeliveryAttempt'
required:
- attempts
WebhookEndpointCreated:
allOf:
- $ref: '#/components/schemas/WebhookEndpoint'
- type: object
properties:
secret:
type: string
description: Signing secret returned exactly once on create or rotate. Store it immediately.
required:
- secret
WebhookDeliveryAttempt:
type: object
properties:
attempt_number:
type: integer
started_at:
type: string
duration_ms:
type: integer
outcome:
type: string
enum:
- delivered
- retryable
- terminal
status_code:
type:
- integer
- 'null'
status_class:
type: string
diagnostic:
type: string
description: Sanitized diagnostic recorded at attempt time. Never a response body or secret.
required:
- attempt_number
- started_at
- duration_ms
- outcome
- status_code
- status_class
- diagnostic
WebhookEndpoint:
type: object
properties:
id:
type: string
object:
type: string
enum:
- webhook_endpoint
url:
type: string
event_types:
type: array
items:
type: string
status:
type: string
enum:
- enabled
- paused
- failing
failure_streak:
type: integer
minimum: 0
last_failure_at:
type:
- string
- 'null'
last_success_at:
type:
- string
- 'null'
health_changed_at:
type:
- string
- 'null'
health_reason:
type:
- string
- 'null'
enum:
- consecutive_failures
- retry_exhausted
- http_410
- operator_pause
- operator_resume
- synthetic_recovery
- null
secret_overlap_expires_at:
type:
- string
- 'null'
created_at:
type: string
updated_at:
type: string
required:
- id
- object
- url
- event_types
- status
- failure_streak
- last_failure_at
- last_success_at
- health_changed_at
- health_reason
- secret_overlap_expires_at
- created_at
- updated_at
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.'
UpdateWebhookEndpointBody:
type: object
properties:
url:
type: string
maxLength: 2048
format: uri
event_types:
type: array
items:
type: string
enum:
- job.created
- job.updated
- job.deleted
- company.created
- company.updated
- company.deleted
- company.verification.updated
- candidate.created
- candidate.updated
- candidate.deleted
- candidate.profile.updated
- candidate.verification.updated
- marketing_permission.granted
- marketing_permission.withdrawn
- digital_product.purchased
- digital_product.refunded
minItems: 1
status:
type: string
enum:
- enabled
- paused
additionalProperties: false
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