Cavuno Webhooks API

Configure Board-owned outbound webhook endpoints, inspect delivery history, and replay completed deliveries.

Operations 10

GET /webhook-endpoints List webhook endpoints #
POST /webhook-endpoints Create a webhook endpoint #
GET /webhook-endpoints/{id} Retrieve a webhook endpoint #
PATCH /webhook-endpoints/{id} Update a webhook endpoint #
DELETE /webhook-endpoints/{id} Retire a webhook endpoint #
POST /webhook-endpoints/{id}/rotate-secret Rotate a webhook endpoint secret #
POST /webhook-endpoints/{id}/test Send a synthetic test delivery #
GET /webhook-deliveries List webhook deliveries #
GET /webhook-deliveries/{id} Retrieve a webhook delivery #
POST /webhook-deliveries/{id}/replay Replay a webhook delivery #

Work with this as data

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 Specification

cavuno-com-webhooks-api-openapi.yml Raw ↑
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