{
  "openapi": "3.0.4",
  "info": {
    "title": "Kenso API",
    "description": "The **Kenso API** is the API the Kenso app itself runs on. This reference lists its public\nendpoints: campaigns, sequences, contacts, segments, inboxes, threads, domains, search,\nwebhooks and more. They are a stable contract: we add fields and endpoints, and we do not\nremove or rename them without a new dated version. Every change is listed in the\n[changelog](https://developer.ken.so/changelog/).\n\nThe **Client API v2** stays available as the Legacy v2 document on this site and at\n[`/v2/docs`](/v2/docs).\n\nThis site is the interactive reference: every endpoint with its parameters, request and\nresponse shapes, and a ready request to copy. The same reference, readable without\nJavaScript, and the guides are on [ken.so/docs](https://ken.so/docs):\n[authentication](https://ken.so/docs/authentication), [workspaces](https://ken.so/docs/workspaces),\n[versioning](https://ken.so/docs/versioning), [pagination](https://ken.so/docs/pagination) and\n[errors](https://ken.so/docs/errors).\n\n## Base URL and version\n\nEvery endpoint is under `https://api.ken.so/v1`. Versions are dates. Send the version you\nbuilt against in `Ken-Version`, for example `Ken-Version: 2026-11-02`. `1.1` is an alias of\nthe first dated version. A version stays supported until twelve months after the next one\nships; the changelog lists every version's date, and responses on a version with a\nretirement date carry `Deprecation` and `Sunset` headers. A retired version answers\n`400 version_retired`, and an unknown one `400 unsupported_version`.\n\nA new version changes only the operations the changelog names. Requests and responses on an\nolder version are converted, so your integration keeps its shapes until you move it.\n\n```http\nGET /v1/campaigns HTTP/1.1\nHost: api.ken.so\nAuthorization: Bearer ken_<your_key>\nKen-Version: 2026-11-02\nX-Ken-Workspace-Id: 812\n```\n\n### Keys are pinned to a version\n\nEvery API key is pinned to a version when you create it, the newest by default. A request\nwith the key and no `Ken-Version` header gets the pinned version, so a script needs no\nheader. A header on the request wins over the pin. Change a key's pin in the Kenso app under\n**Settings > Integrations > API Keys**. A key pinned to `legacy` has no version: without the header it reaches\nthe older shape some paths still serve, as keys did before versions existed. Keys created\nbefore versions existed are pinned to `legacy`.\n\n## Authentication\n\nSend a Kenso API key as a Bearer token. Keys start with `ken_`. Create one in the Kenso app\nunder **Settings > Integrations > API Keys**. The key is shown once, when you create it. A key\nacts with the role you have in the workspace, so an endpoint your role cannot use answers\n`403`. A missing, invalid or revoked key answers `401`.\n\n## Workspaces\n\nPick the workspace with the `X-Ken-Workspace-Id` header. When your key reaches exactly one\nworkspace you can leave it out. When it reaches more than one, a request without it answers\n`400 workspace_required`. A resource in a workspace you are not a member of answers\n`404 not_found`, the same as one that does not exist.\n\n## Rate limits\n\nLimits are per workspace, per minute, by the kind of call:\n\n| Kind | Limit |\n|------|-------|\n| Read (`GET`) | 3,000 per minute |\n| Write (`POST`, `PATCH`, `PUT`, `DELETE`) | 1,200 per minute |\n| Bulk (bulk endpoints such as `bulk-create`, and imports) | 120 calls per minute and 1,000,000 items per day |\n| Heavy (search, exports, analytics, AI runs) | 60 per minute |\n| Sensitive (API keys, members, billing, webhooks, integrations) | 30 per minute |\n\nAll calls together are limited to 1,000,000 per workspace per day. These are the standard\nlimits; your plan can change them. Responses carry `RateLimit-Limit`, `RateLimit-Remaining`\nand `RateLimit-Reset`. Over a limit the response is `429` with `Retry-After`; wait that long\nand retry. Spread bulk work over the day rather than bursting it.\n\n## Responses\n\nA single resource:\n\n```json\n{ \"success\": true, \"data\": { \"id\": 812, \"name\": \"Q4 SaaS founders\" } }\n```\n\nA list, paged with a cursor:\n\n```json\n{\n  \"success\": true,\n  \"data\": [ { \"id\": 812 }, { \"id\": 815 } ],\n  \"pagination\": { \"nextCursor\": \"eyJpZCI6ODE1fQ\", \"hasMore\": true }\n}\n```\n\nPass `limit` and the previous page's `nextCursor` as `cursor`. `limit` defaults to 50. Most\nlists accept up to 200 and answer `400` above that. Search lists return at most 100 per page.\nCursors are opaque. Stop when `hasMore` is false.\n\n- Fields are camelCase. Ids are integers, except thread (`thr_...`), message (`msg_...`) and\n  attachment (`att_...`) ids, which are opaque strings.\n- Times are UTC ISO 8601 (`2026-09-23T15:02:11Z`). Calendar dates are `YYYY-MM-DD`.\n- Enums are lowercase snake_case strings, except where an operation's schema lists other values:\n  segment filter operators are PascalCase (`NotExists`), and the `contacts.search` filter\n  operators and data types are integers. Treat an unknown value as possible: we add values.\n- Fields that are `null` are left out of the response.\n\n## Feature flags\n\nSome operations need a feature turned on for your workspace. Their descriptions say so. Until\nthe feature is on, those calls answer `404`.\n\n## Errors\n\nErrors from the endpoints use one shape and a matching HTTP status:\n\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"validation_failed\",\n    \"message\": \"Campaign name is required.\",\n    \"details\": [ { \"field\": \"name\", \"code\": \"required\", \"message\": \"Name is required.\" } ],\n    \"requestId\": \"0HN7Q2...\"\n  }\n}\n```\n\nBranch on `code`, which is stable. `message` is for people and can change. Quote `requestId`\nwhen you contact support.\n\n| Status | `code` |\n|--------|--------|\n| 400 | `validation_failed`, `workspace_required`, `unsupported_version`, `version_retired` |\n| 401 | `unauthenticated` |\n| 402 | `plan_limit_reached` |\n| 403 | `forbidden` |\n| 404 | `not_found` |\n| 409 | `conflict`, `invalid_state` |\n| 429 | `rate_limited`, `quota_exceeded` |\n| 500 | `internal_error` |\n| 503 | `service_unavailable` |\n\nSome `401` and `429` responses come from the authentication and rate-limit layers in front\nof the endpoints. Those responses do not use the shape above. Branch on the HTTP status for\nthem:\n\n- `401`: the API key is missing, invalid or revoked. The body is\n  `{ \"error\": \"Invalid or revoked API key\" }` or empty.\n- `429`: your key or your IP sent too many requests. Wait and retry, honoring `Retry-After`\n  when the response carries it.",
    "version": "1.1"
  },
  "paths": {
    "/v1/access-requests": {
      "post": {
        "tags": [
          "access-requests"
        ],
        "summary": "Ask for a page, a feature or a higher credit limit.",
        "description": "`{ kind, key, level?, reason? }`. Page: `key` is a page and `level` is view or edit (omitted =\n            one level above what you have). Feature: `key` is a feature. Credits: `key` is `monthly_limit`;\n            the grant sets the limit. Asking for what you already have is `validation_failed` with the detail code\n            `already_granted`. You can have one pending request per kind and key: asking again returns it with 200.\n            A new request (201) emails every member who manages members. Any member of the workspace.\n\nNeeds the `permissions` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "access-requests.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccessRequestBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccessRequestBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAccessRequestBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "permissions"
        ]
      },
      "get": {
        "tags": [
          "access-requests"
        ],
        "summary": "List access requests, newest first.",
        "description": "Members who manage members (and staff) see every request in the workspace; everyone else sees their own.\nFilter with `status` (pending, granted, declined, canceled). `limit` is 1..100 (default 50).\n\nNeeds the `permissions` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "access-requests.list",
        "parameters": [
          {
            "name": "Status",
            "in": "query",
            "description": "pending, granted, declined, or canceled. Omitted = every status.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "1..100, default 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAccessRequestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAccessRequestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAccessRequestModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "permissions"
        ]
      }
    },
    "/v1/access-requests/{accessRequestId}/cancel": {
      "post": {
        "tags": [
          "access-requests"
        ],
        "summary": "Cancel your own pending request.",
        "description": "Only the person who asked; anyone else is `403 forbidden`. A request that is no longer pending is `409 invalid_state`.\n\nNeeds the `permissions` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "access-requests.cancel",
        "parameters": [
          {
            "name": "accessRequestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAccessRequestModel"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "permissions"
        ]
      }
    },
    "/v1/agent-team/runway": {
      "get": {
        "tags": [
          "agent-team"
        ],
        "summary": "Return how long each live campaign's leads last and whether its inboxes can carry the send.",
        "description": "Without `campaignId`: the workspace's live campaigns (scheduled, sending, launching), newest first, at most\n50. With it: that campaign in any status, `404` when it is not in the workspace. Per campaign: Autopilot,\nthe leads waiting for their first email and the days they last at the last 7 days' rate, the daily cap against\nthe healthy inboxes' limits, each inbox's 7-day sends and bounce rate and why it is sick, the latest placement\ntest, and the email interested replies. Reads only. Campaigns view.\n\nNeeds the `agent_templates` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "agent-team.get-runway",
        "parameters": [
          {
            "name": "campaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRunwayModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRunwayModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRunwayModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "agent_templates"
        ]
      }
    },
    "/v1/agent-team/actions": {
      "post": {
        "tags": [
          "agent-team"
        ],
        "summary": "Ask for one bounded change to a campaign: applied when it is inside Autopilot and the bounds, else proposed.",
        "description": "Body: `kind` (`cap_move`, `inbox_drop`, `inbox_restore`, `top_up`, `placement_test` or\n`make_default`), `campaignId`, `args` for the kind, `reason` (up to 500 characters) and an optional\n`idempotencyKey` (up to 120). Every outcome is `200` with `status`: `applied` (the change is made and\nrecorded as the caller's, with `actionId` and the undo deadline), `proposed` (Autopilot is off, a standing\nrule holds the campaign, or the change is outside the bounds: a person decides it in Approvals, `approvalId`), or\n`refused` (`code` and `message`; nothing changed). A lead top-up runs as a person, so an API key with no\nuser is refused `needs_a_user`, and it also needs Search view and the Import permission (else `403``permission_denied`). A retry with the same key, or without one the same request on the same UTC day, runs once;\nwithout a key a try that failed runs again. The tool that sent it (`X-Ken-Client`) names the caller in the\nhistory. Campaigns edit.\n\nNeeds the `agent_templates` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "agent-team.create-action",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAgentActionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAgentActionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAgentActionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentActionOutcomeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentActionOutcomeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentActionOutcomeModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "agent_templates"
        ]
      }
    },
    "/v1/agent-team/actions/{actionId}/undo": {
      "post": {
        "tags": [
          "agent-team"
        ],
        "summary": "Undo an applied agent action inside its undo window.",
        "description": "Puts back what the action changed, as the caller: the previous cap, the dropped inbox, the default before; a top-up\nremoves only the leads that have not started (no email sent or queued). `404` when the action is not in the\nworkspace; `400` when it is already undone or failed, its window has closed, or the undo would overwrite a newer\nchange (the action stays in effect with the reason). Returns the action. Campaigns edit.\n\nNeeds the `agent_templates` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "agent-team.undo-action",
        "parameters": [
          {
            "name": "actionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentActionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentActionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentActionModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "agent_templates"
        ]
      }
    },
    "/v1/agent-team/changes": {
      "get": {
        "tags": [
          "agent-team"
        ],
        "summary": "Return what changed on the workspace's campaigns since a time, by default since the caller last asked.",
        "description": "`since` (ISO 8601) defaults to the caller's previous call from the same tool (`X-Ken-Client`), else 7 days\n            ago, and is never more than 30 days back. Without `campaignId` the change log covers the live campaigns\n            (scheduled, sending, launching). Returns the change log rows (newest first, at most 200, `truncated` when there\n            were more) with who made each and its `requestId`, the agent actions applied (an undone top-up with the leads it\n            kept), the proposals open now and those decided in the window, and the standing rules in force. Reads only.\n            Campaigns view; `proposals` is null unless the caller also has Campaigns edit and Approve, as Approvals.\n\nNeeds the `agent_templates` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "agent-team.list-changes",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "campaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentTeamChangesModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentTeamChangesModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentTeamChangesModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "agent_templates"
        ]
      }
    },
    "/v1/agent-team/proposals": {
      "post": {
        "tags": [
          "agent-team"
        ],
        "summary": "Propose a change a person decides in Approvals.",
        "description": "Body: `kind`, `campaignId` (omit for `angle`, `standing_rule` and `client_update`),\n`title` (up to 120 characters), `reason` (up to 1000), `args` for the kind, and optionally\n`clientYes` (the client's yes in their own words, up to 300; the approver still confirms it) and `urgent`.\nReturns `201` with the proposal, `request_<id>`, as `/v1/approvals` lists it. `400``unknown_kind`, `kind_not_allowed` or `invalid_args` with the reason (`campaign_not_found` when a\ncampaign kind names no campaign); `404``campaign_not_found` when the campaign is not in the workspace,\ndeleted or archived. The tool that sent it (`X-Ken-Client`) names the requester on the card. Campaigns edit.\n\nNeeds the `agent_templates` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "agent-team.create-proposal",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProposalRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProposalRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProposalRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentProposalModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentProposalModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAgentProposalModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "agent_templates"
        ]
      },
      "get": {
        "tags": [
          "agent-team"
        ],
        "summary": "List the workspace's proposals, newest first.",
        "description": "`status`: `open` (pending or awaiting the client) or one status as it reads now (a pending proposal past\n            its expiry reads `expired`); `campaignId`; `limit` 1-100, default 25; `cursor` from the previous\n            page. A status filter applies within each page, so a page can hold fewer than `limit` while\n            `pagination.hasMore` is true. Campaigns edit and Approve, as Approvals.\n\nNeeds the `agent_templates` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "agent-team.list-proposals",
        "parameters": [
          {
            "name": "Status",
            "in": "query",
            "description": "`open` (pending or awaiting the client), `pending`, `awaiting_client`, `applied`, `rejected`,\n            `expired`, `superseded` or `failed`. Omit for every status.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "1 to 100, default 25.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAgentProposalModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAgentProposalModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAgentProposalModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "agent_templates"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/ai-line-holds": {
      "get": {
        "tags": [
          "ai-line-holds"
        ],
        "summary": "List the contacts the AI line check held in a campaign.",
        "description": "Newest hold first, with the reasons and the lines each hold keeps. Pages with `limit` (1 to 200, default 50)\nand `cursor`. A contact appears until it is approved or regenerated. A campaign outside the workspace is\n`not_found`. Requires `ReadAccess`.",
        "operationId": "ai-line-holds.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAiLineHoldModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAiLineHoldModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAiLineHoldModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/ai-line-holds/{contactId}/approve": {
      "post": {
        "tags": [
          "ai-line-holds"
        ],
        "summary": "Approve a held contact's lines.",
        "description": "The lines the hold keeps become the contact's personalization lines and the contact counts as personalized, so it\ncan send. Not charged. A contact with no hold in the campaign (never held, already approved, or regenerated) is\n`not_held` (409). When the contact already has a live line for one of the held variables the approval is\n`conflict` (409) and nothing changes; regenerate the contact instead. A campaign or contact outside the\nworkspace, or a contact not in this campaign, is `not_found`. Requires `WriteAccess`.",
        "operationId": "ai-line-holds.approve",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiLineHoldApprovalModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiLineHoldApprovalModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiLineHoldApprovalModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/{contactId}/ai-lines": {
      "get": {
        "tags": [
          "ai-lines"
        ],
        "summary": "List a contact's AI lines.",
        "description": "One line per AI variable of the contact's campaign: the stored line its next send renders (the newest\npersonalized line, or its rewrite when the prompt rewrites; the segment's prompt before the campaign's).\nOlder runs and replaced lines are not listed. Ordered by variable, at most 200 lines, not paginated. A\ncontact outside the workspace, deleted, or not in a campaign is `not_found`.\nRequires `ReadAccess`.\n\nNeeds the `ai_line_edit` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "ai-lines.list",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactAiLineModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactAiLineModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactAiLineModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ai_line_edit"
        ]
      }
    },
    "/v1/contacts/{contactId}/ai-lines/{aiLineId}": {
      "patch": {
        "tags": [
          "ai-lines"
        ],
        "summary": "Replace the text of one of a contact's AI lines.",
        "description": "The next send of the lead renders the new text, and an approval draft that shows the lead is updated.\nSteps already sent keep what they sent. `text` is required, at most 4,000 characters; it gets the\ncleanup a generated line gets (emoji removed, dashes normalized, spaces collapsed) and must be 1 to 1,000\ncharacters after it, else `validation_failed`. Another of the contact's lines that the send does not read\n(an older run, a personalized line its rewrite replaces) is `409 invalid_state` and nothing changes; list\nthe lines again and edit the one shown. A line that is not the contact's is `not_found`.\nRequires `WriteAccess`.\n\nNeeds the `ai_line_edit` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "ai-lines.update",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "aiLineId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactAiLineRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactAiLineRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactAiLineRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactAiLineModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactAiLineModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactAiLineModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ai_line_edit"
        ]
      }
    },
    "/v1/contacts/{contactId}/ai-lines/regenerate": {
      "post": {
        "tags": [
          "ai-lines"
        ],
        "summary": "Write a contact's AI lines again.",
        "description": "Clears the contact's personalized lines (and the rewritten lines built on them) and queues a personalization\nrun for that contact alone, charged as one lead. Returns `202` with the run; poll\n`GET /v1/ai-runs/{aiRunId}`. When the run lands, an approval draft that shows the lead is updated.\nA lead already sent or exported, with a send queued, or in an unfinished AI run is `409 invalid_state`\nand nothing changes. AI quota limits answer `429 quota_exceeded` and too few credits `402`, both\nbefore anything is cleared, so the lead keeps its lines. Only a full AI run queue (`503`) after the clear\nleaves the lead without lines until a retry or the next scheduled AI run.\nRequires `WriteAccess`.\n\nNeeds the `ai_line_edit` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "ai-lines.regenerate",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ai_line_edit"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/ai-runs": {
      "post": {
        "tags": [
          "ai-runs"
        ],
        "summary": "Queue an AI run for a campaign in the current workspace.",
        "description": "Returns `202` with a run id. Poll `GET /v1/ai-runs/{aiRunId}`.\nA campaign outside `X-Ken-Workspace-Id` is `not_found` before the run is queued.\nWith `dryRun: true` the request is validated the same way and the answer is `200` with what the run would\nprocess: `batchSize` (the requested batch, else the flow's submission limit when `processAll`, else 500),\n`eligibleCount` (eligible contacts now, in `segmentId` when set), `projectedContactCount` (the lower\nof the two, an upper bound) and the flow's `blockingGate` and `blockingReason`. Nothing is queued, no\nquota is reserved and no credits are spent.\nRequires `WriteAccess`.",
        "operationId": "ai-runs.create",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAiRunRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAiRunRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAiRunRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunDryRunModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunDryRunModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunDryRunModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/ai-runs/{aiRunId}": {
      "get": {
        "tags": [
          "ai-runs"
        ],
        "summary": "Read one AI run.",
        "description": "The run's campaign must belong to `X-Ken-Workspace-Id`. A missing run, or a run outside\nthe workspace, is `not_found`. Requires `ReadAccess`.",
        "operationId": "ai-runs.get",
        "parameters": [
          {
            "name": "aiRunId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/ai-runs/eligibility": {
      "get": {
        "tags": [
          "ai-runs"
        ],
        "summary": "Read AI-run eligibility for a campaign, with an optional invalidation preview.",
        "description": "Replaces eligible counts and the invalidation preview. Pass `flow` and `preview`\n(`freshness` or `reset`) to include the preview. A campaign outside the workspace\nis `not_found` before either read. Requires `ReadAccess`.",
        "operationId": "ai-runs.get-eligibility",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "SegmentId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Flow",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Preview",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunEligibilityModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunEligibilityModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunEligibilityModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/ai-runs/reset": {
      "post": {
        "tags": [
          "ai-runs"
        ],
        "summary": "Reset an AI flow and the flows that depend on it.",
        "description": "A campaign outside the workspace is `not_found` before the reset. Requires Campaigns edit access (owners, admins and editors by default).",
        "operationId": "ai-runs.reset",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetAiRunRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetAiRunRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ResetAiRunRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunResetModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunResetModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunResetModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/ai-runs/reset-contacts": {
      "post": {
        "tags": [
          "ai-runs"
        ],
        "summary": "Reset personalization or rewriting for chosen contacts of a campaign.",
        "description": "DEV-3008. Only the listed contacts (1 to 500 ids) are reset, for the flow and the flows that depend on it;\nnothing campaign-wide is cancelled. Ids that are not contacts of the campaign, contacts already sent or\nexported, contacts with a send queued, and contacts inside an active batch come back in\n`contactsSkipped` and are not touched. A campaign outside the workspace is `not_found`.\nThis is its own route rather than a field on `reset`: a build without it answers 404, while a build\nbefore DEV-3008 would ignore a `contactIds` field on `reset` and reset the whole campaign.",
        "operationId": "ai-runs.reset-contacts",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetAiRunContactsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ResetAiRunContactsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ResetAiRunContactsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunResetModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunResetModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAiRunResetModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/campaign-performance": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Return campaign or workspace performance for a reporting window.",
        "description": "`groupBy` is `day`, `step`, `segment`, `sender_route`, `campaign`, or `language`.\n            `channel` is `email` or `linkedin`.\n            With `campaignId` and neither `from` nor `to`, the window is the campaign to date: from its first send or\n            first imported day, whichever is earlier, in `timeZone` (default UTC), to today, up to 3660 days; `from` and\n            `to` in the response hold it. Without `campaignId`, `from` and `to` are required.\n            `groupBy=sender_route` (email, `campaignId` required) splits the campaign by the sender rule each contact's\n            first email went out under: one row per provider rule (`key` the provider slug, `label` its name),\n            `everyone_else` and `not_routed` (sent with no rules or with sender routing off), each with `routeKey`\n            equal to `key`. A contact stays in one row; its sends, contacted, distinct repliers, interested replies and bounces\n            in the window count there. Opens, clicks, unsubscribes, `bounceBreakdown` and the opportunity and meetings fields\n            are not split by route (0 or absent on the rows). The window `metrics` are the campaign's `groupBy=day` ones,\n            opens and clicks included, so the rows need not add up to them: a contact with no accepted send is in no row.\n            `groupBy=language` (needs `campaignId`) returns one row per language the campaign's emails went out in, keyed by\n            that language, sorted by sends with `unknown` (sends that recorded no language) last: sends, contacted, replies and\n            interested (distinct contacts), the reply rate over contacted. A reply counts in the language of the send it answers.\n            Opens, clicks and bounces are not split by language, and the LinkedIn channel has no language rows (DEV-5321). The window\n            `metrics` are the campaign's `groupBy=day` ones, where a contact emailed in two languages counts once.\n            `groupBy=campaign` (email, no `campaignId`, a window up to 3660 days) returns one row per campaign with email\n            activity in the window, with `campaignId` on each row, in one read: a row's counts are the window metrics that\n            campaign's own `groupBy=day` read returns with the same non-UTC `timeZone`, so lifetime numbers for every\n            campaign take one call. Without a `timeZone` (or with UTC) the rows add up UTC days, while the campaign's own read\n            counts contacted and replies once across the window, so there a contact active on several days counts once per day.\n            Its unique opens add up the campaign's days, its unique clicks count each human clicker once over the UTC window as the\n            campaign's own read does, the opportunity, meetings and `bounceBreakdown` fields are left out, and the window\n            `metrics` add up the rows.\n            Rates are fractions from 0 to 1. Day buckets are UTC calendar dates unless `timeZone` is an IANA zone that is not\n            UTC: then email day rows (`groupBy=day`), their meetings and opportunity cohort count that zone's calendar days, from\n            its midnight on `from` to its midnight after `to`, and the window `metrics` add up the rows; for one\n            campaign, unique opens and unique clicks are the campaign window's, as without a zone. Opens, unique opens and\n            unsubscribes count that zone's days too. Imported history and days before 2026-08-24 stay on UTC days: imported history arrives from\n            each vendor as date-only day buckets (Instantly `yyyy-MM-dd`, Smartlead and Apollo day buckets,\n            `SourceDailyStat.Date` is a `DateOnly`), so it has no time of day to move. Step, segment and sender_route rows\n            and the LinkedIn channel count the window from the zone's midnights too (DEV-5365, DEV-5225); a segment row's opens and unsubscribes\n            stay on their stored UTC days. `groupBy=inbox` is served by deliverability.\n            Email `openCount`, `uniqueOpenCount` and `openRate` count human opens; `machineOpenCount` (window\n            metrics and step rows) counts contacts whose every open was a machine open (Apple MPP, a crawler, or an open within a\n            minute of the send). Opens are an estimate and a floor, never the headline: reply rate is.\n            Email `clickCount` is Kenso-tracked human clicks; `botClickCount` is separate. The window\n            `metrics` carry `bounceBreakdown` (type and reason split) when a categorized bounce exists.",
        "operationId": "analytics.get-campaign-performance",
        "parameters": [
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "From",
            "in": "query",
            "description": "First day of the window. With to; leave both out with campaignId for the campaign to date.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "description": "Last day of the window, inclusive.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "GroupBy",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Channel",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "TimeZone",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignPerformanceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignPerformanceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignPerformanceModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/engagement": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Return a ranked engagement breakdown for one campaign.",
        "description": "`dimension` is `device`, `browser`, `os`, `country`, `region`, `city`,\n            `referrer`, `network`, `link`, or `source`. Blank defaults to `device`.\n            `limit` is a top-N cap from 1 to 200 (default 50). `country` filters the city dimension.\n            `segmentId` filters region, network, referrer, and source.",
        "operationId": "analytics.get-engagement",
        "parameters": [
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Dimension",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "SegmentId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEngagementModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEngagementModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEngagementModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/deliverability": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Return workspace deliverability for a reporting window.",
        "description": "`groupBy` is `day`, `domain`, or `inbox`. Rates are fractions from 0 to 1.\n            Day buckets are UTC calendar dates. With a `timeZone` that is not UTC, day, domain and inbox rows count sequencer\n            sends, replies, bounces and out-of-office replies on that zone's days, from its midnight on `from` to its\n            midnight after `to`, and the window `sentCount`, `replyCount`, `bounceCount`, `clickCount`\n            and rates are the sums of the day rows. Complaints are kept per domain per UTC day with no time of day, so they stay\n            on UTC days. Clicks carry no sending inbox, so delivery rows hold none to move. `limit` caps domain and inbox\n            rows (1 to 200, default 50).\n            Domain and inbox rows carry `reputation` (`paused`, `at_risk`, `watch`, `good` or\n            `unknown`) and `alerts`, plain-language alerts with a `code`, `scope`, `severity`,\n            `message` and recommended `action`, built from stored signals: enforced send pauses, blocklists, SPF, DKIM\n            and DMARC checks, placement tests, complaints, recipient refusals and, on inbox rows, bounce rates, Microsoft tenant\n            bans and sender rejections. An inbox row also carries its domain's alerts. Day rows carry neither. New alert codes may be added.\n            Reputation and alerts describe the state now; only `complaint_rate` and `high_bounce_rate` count the window.",
        "operationId": "analytics.get-deliverability",
        "parameters": [
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "GroupBy",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "TimeZone",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDeliverabilityModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDeliverabilityModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDeliverabilityModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/deliverability-gates": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Return the bounce gates in force and each domain's and inbox's verdict for the last 24 hours.",
        "description": "Read-only (DEV-5210). Counts accepted cold and 1:1 sends and hard bounces over the last 24 hours, as the sequencer's\nbounce signal does, and judges each row by the gate the sequencer enforces (`Sequencer:SendBlocks:Bounce`):\ninbox rows by the inbox block gate, domain rows by the campaign pause gate (there is no domain bounce block).\nA row is `over` when its rate is strictly above `threshold` with at least `minSends` sends and\n`minBounces` hard bounces, `watch` when it is not over and its rate is at or above 80% of the threshold,\nand `ok` otherwise. `isSmallSample` marks a row with fewer sends than `minSends`, which cannot be\n`over`. The sequencer itself judges over `enforcedWindowHours`; `isEnforced` is false while it only\nrecords. A mailbox with no managed domain counts toward its address's domain, except on a free-mail provider\n(gmail.com), where it has an inbox row only. Rates are fractions from 0 to 1. Rows are worst first; `limit`\ncaps each list (1 to 200, default 50).",
        "operationId": "analytics.get-deliverability-gates",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDeliverabilityGatesModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDeliverabilityGatesModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDeliverabilityGatesModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/reply-classifications": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Return reply classification counts for a reporting window.",
        "description": "Classification names are lowercase snake_case. `interestedCount` is the interested class.\nCounts are people, not messages: a contact counts once per row, in one class (interested if any of its messages\nis, else its latest reply's class, else its latest message's).\nOptional `campaignId` must belong to the workspace. `byCampaign`, `bySegment`, and\n`byConfiguration` add those breakdowns. Replies count by the time they came in, from UTC midnight on\n`from` to UTC midnight after `to`, unless `timeZone` is an IANA zone that is not UTC: then from that\nzone's midnight on `from` to its midnight after `to`, totals and breakdowns alike.",
        "operationId": "analytics.get-reply-classifications",
        "parameters": [
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "SegmentId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "ConfigurationId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "ByCampaign",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "BySegment",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "ByConfiguration",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "TimeZone",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyClassificationsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyClassificationsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyClassificationsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/query": {
      "post": {
        "tags": [
          "analytics"
        ],
        "summary": "Run an analytics query: metrics split by up to two dimensions over a window, with an optional previous period.",
        "description": "Needs the `generative_ui` flag (404 while it is off). `metrics` holds 1 to 8 names, `groupBy` at most 2\ndimensions, `limit` at most 200 rows, and the window at most 400 days. A `null` dimension value is Unknown.\nBy default (`rateBasis``event_time`) rates are event-time ratios: numerator and denominator are counted by event\ntime inside the same window and group, so a rate is usually 0 to 1 but can exceed 1 in short windows, `day` or\n`week` buckets or by `step` when replies or accepts answer earlier sends (a verdict on such counts is\n`too_early`); it is `null` on a zero denominator. `rateBasis``cohort` counts each reply and accept\nagainst the send it answers, in that send's group and day, whenever it arrived, so replies, interested, not interested,\naccepted and their rates stay within the group's contacted and invites (0 to 1); every row and the totals then carry\n`stillFilling`, true while most of their sends are under 7 days old. Other counts are event-time on both bases.\n`previous` is null without `compareTo`. With it, rows grouped by `day` or `week` get `previous`\nnull (the previous window holds other dates; only a week straddling both windows matches its earlier days), so only the\ntotals compare. Each call counts on the workspace's `analyticsQueries` quota.\n\nNeeds the `generative_ui` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "analytics.query",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsQueryRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsQueryRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/AnalyticsQueryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAnalyticsQueryResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAnalyticsQueryResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAnalyticsQueryResult"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "generative_ui"
        ]
      }
    },
    "/v1/analytics/variant-performance": {
      "get": {
        "tags": [
          "analytics"
        ],
        "summary": "Return one campaign's contacts, replies and interested replies split by step and variant.",
        "description": "DEV-5244: the analytics query with a fixed shape, so a member, an editor and a client seat read which variant of a\nstep wins without the `generative_ui` flag. Behind its own `variant_performance` flag (404 while it is off\nfor the workspace). Metrics are `contacted`, `replies`, `interested`,\n`reply_rate` and `positive_reply_rate`, grouped by `step` and `variant`, counted the query's way:\ndistinct contacts per row; replies come from the inbox, and out-of-office and the other non-replies do not count.\nIt reads on the query's cohort basis: each reply counts against the step and variant of the send it answers, whenever\nit arrived, so replies and interested stay within `contacted` and the rates are 0 to 1 (`null` when nobody\nwas contacted). Every row and the totals carry `stillFilling`, true while most of their sends are under 7 days\nold and replies to them are still arriving. `from` and `to` are inclusive calendar days in `timeZone` (default the campaign's sending zone, else\nUTC), at most 400 days; leave both out for the campaign to date. Email and LinkedIn rows both come back: LinkedIn rows\nread \"LinkedIn step N\" and \"LinkedIn variant X\", and a contact with no variant is the Unknown row. A campaign of\nanother workspace is 404. Each call counts on the workspace's `analyticsQueries` quota. Campaigns view.\n\nNeeds the `variant_performance` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "analytics.get-variant-performance",
        "parameters": [
          {
            "name": "CampaignId",
            "in": "query",
            "description": "Required: a campaign of the workspace.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "From",
            "in": "query",
            "description": "First calendar day of the window (`YYYY-MM-DD`, inclusive). With `to`; neither is the campaign to date.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "To",
            "in": "query",
            "description": "Last calendar day of the window (`YYYY-MM-DD`, inclusive).",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "TimeZone",
            "in": "query",
            "description": "IANA zone the days are in; default the campaign's sending zone, else UTC.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAnalyticsQueryResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAnalyticsQueryResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAnalyticsQueryResult"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "variant_performance"
        ]
      }
    },
    "/v1/attachments": {
      "post": {
        "tags": [
          "attachments"
        ],
        "summary": "Upload a pending attachment for an email message.",
        "description": "Multipart field `file` and form field `messageId` (`msg_`, email only).\nCaps stay at 5 files, 8 MiB each, and 10 MiB pending. Requires `InboxReplyAccess`.",
        "operationId": "attachments.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "messageId": {
                    "type": "string"
                  }
                }
              },
              "encoding": {
                "file": {
                  "style": "form"
                },
                "messageId": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAttachmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAttachmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAttachmentModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/attachments/{attachmentId}/content": {
      "get": {
        "tags": [
          "attachments"
        ],
        "summary": "Download attachment bytes.",
        "description": "A malformed id is `not_found`. `inline=true` is only honored for an inline image.\nRequires `ReadAccess`.",
        "operationId": "attachments.get-content",
        "parameters": [
          {
            "name": "attachmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "inline",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "text/json": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/v1/attachments/{attachmentId}": {
      "delete": {
        "tags": [
          "attachments"
        ],
        "summary": "Delete a pending attachment that has not been sent.",
        "description": "Returns `204`. A malformed id is `not_found`. Requires `InboxReplyAccess`.",
        "operationId": "attachments.delete",
        "parameters": [
          {
            "name": "attachmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/auto-pauses": {
      "get": {
        "tags": [
          "auto-pauses"
        ],
        "summary": "List the inboxes, domains and campaigns Ken paused on its own.",
        "description": "Newest first. Only pauses Ken enforced: bounce, complaint, Gmail spam-rate, placement,\nblocklist, DNS and reply-ingest send blocks, and campaign pauses after hard send failures.\nLists pauses that started at or after `since` (default 7 days ago, at most 30 days back)\nplus any older pause still active. A renewal of a block still in force is the same pause.\n`isActive` is true while the target is still blocked or paused. Rates are fractions\nfrom 0 to 1. Read-only. Requires view access to the campaigns page, like deliverability.",
        "operationId": "auto-pauses.list",
        "parameters": [
          {
            "name": "Since",
            "in": "query",
            "description": "Window start (UTC). Default 7 days ago; anything older than 30 days is read as 30.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAutoPauseModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAutoPauseModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAutoPauseModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/autonomous-reply-settings": {
      "get": {
        "tags": [
          "autonomous-reply-settings"
        ],
        "summary": "Return autonomous reply settings for the current workspace.",
        "description": "Requires `ReadAccess`.",
        "operationId": "autonomous-reply-settings.get",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAutonomousReplySettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAutonomousReplySettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAutonomousReplySettingsModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "autonomous-reply-settings"
        ],
        "summary": "Update autonomous reply settings.",
        "description": "Absent fields stay unchanged. JSON null clears `extraInstructions`.\n`mode` is `draft` or `autonomous`, or `approve_risky` where the workspace has the\n`reply_agent_approve_risky` flag on; elsewhere `approve_risky` gets the same `400 validation_failed`\non `mode` as an unknown mode. A body without `mode` keeps the stored mode. Requires `WriteAccess`.",
        "operationId": "autonomous-reply-settings.update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAutonomousReplySettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAutonomousReplySettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfAutonomousReplySettingsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocklist-entries/bulk-create": {
      "post": {
        "tags": [
          "blocklist-entries"
        ],
        "summary": "Add up to 1,000 blocklist values of one type.",
        "description": "Send `values`, or `entries` (`[{ \"value\": \"...\", \"reason\": \"...\" }]`) for a reason per value, not\nboth. Optional `reason` applies to every value without its own. Per-value outcomes are `succeeded` or\n`failed`. Duplicates stay failed with `already_exists` and keep their own reason. A domain a customer\naccount or a blocklist rule already lists becomes `manual` under its id, with the reason sent, and is in\n`succeeded` with `claimed: true`, as on the single add. A shared mail provider domain (gmail.com,\nhotmail.co.uk, web.de) fails with `shared_mail_provider`; any other malformed value with `invalid`.\nTo undo the add, bulk-delete only the `succeeded` ids without `claimed: true`: a claimed entry was\nblocked before the add, and deleting it unblocks the domain. Requires `WriteAccess`.",
        "operationId": "blocklist-entries.bulk-create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateBlocklistEntriesRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateBlocklistEntriesRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkCreateBlocklistEntriesRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocklist-entries/bulk-delete": {
      "post": {
        "tags": [
          "blocklist-entries"
        ],
        "summary": "Remove up to 1,000 blocklist entries by id.",
        "description": "Body `{ \"ids\": [...] }`. Removes them in one transaction and runs the own-domain and rule reconciles once, so\nundoing a large upload takes one call per 1,000 entries. To undo a bulk add, send only its `succeeded` ids\nwithout `claimed: true`: a claimed entry was blocked before the add (by a customer account or a rule), and a\ncustomer entry deleted here stays off. `succeeded` lists every id that is off the blocklist\nafter the call, in request order, including an id already gone. An own-domain entry, and a rule entry while\nblocklist rules are on, stay and are in `failed` with `invalid_state` and the single delete's message.\nRequires `WriteAccess`.",
        "operationId": "blocklist-entries.bulk-delete",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteBlocklistEntriesRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteBlocklistEntriesRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteBlocklistEntriesRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistBulkDeleteResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistBulkDeleteResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistBulkDeleteResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocklist-entries": {
      "get": {
        "tags": [
          "blocklist-entries"
        ],
        "summary": "List blocklist entries in the current workspace.",
        "description": "Ordered by id, which follows creation: `sort=createdAt` (the default) is oldest first, `sort=-createdAt`\nnewest first; keep the same `sort` while paging. Optional filters: `type` (`email` or\n`domain`), `value` (an exact match), `q` (a case-insensitive substring of the value or the reason),\n`source` (comma-separated `manual`, `own_domain`, `customer`, `rule`) and `hasReason`.\n`includeTotal=true` adds `pagination.total`, every entry the filters match. `includeCounts=true` adds\n`counts`: the workspace's entries in all, emails, domains, from the CRM (`customer` and `rule`) and\nwith no reason, whatever the filters. Requires `ReadAccess`.",
        "operationId": "blocklist-entries.list",
        "parameters": [
          {
            "name": "Type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Value",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "description": "Case-insensitive substring of the value or the reason.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Source",
            "in": "query",
            "description": "Comma-separated sources, any of `manual`, `own_domain`, `customer` and `rule`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "HasReason",
            "in": "query",
            "description": "`true` lists entries with a reason, `false` those without one.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Sort",
            "in": "query",
            "description": "`createdAt` (oldest first, the default) or `-createdAt` (newest first).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IncludeTotal",
            "in": "query",
            "description": "`true` adds `pagination.total`, every entry the filters match.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IncludeCounts",
            "in": "query",
            "description": "`true` adds `counts`, the workspace's entries per filter.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/BlocklistEntryListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlocklistEntryListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/BlocklistEntryListResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "blocklist-entries"
        ],
        "summary": "Add one email or domain to the blocklist.",
        "description": "Optional `reason` (at most 200 characters) says why the value is blocked. A duplicate entry is\n`validation_failed` and keeps its own reason. A domain a customer account or a blocklist rule already lists\nbecomes `manual` under its id, with this reason, and comes back with `claimed: true`. A shared mail\nprovider domain (gmail.com, hotmail.co.uk, web.de) is `validation_failed` with detail code\n`shared_mail_provider`: block those addresses one by one. Requires `WriteAccess`.",
        "operationId": "blocklist-entries.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlocklistEntryRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlocklistEntryRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlocklistEntryRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistEntryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistEntryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistEntryModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocklist-entries/{entryId}": {
      "delete": {
        "tags": [
          "blocklist-entries"
        ],
        "summary": "Remove one blocklist entry.",
        "description": "Requires `WriteAccess`. An entry outside the workspace is `not_found`.",
        "operationId": "blocklist-entries.delete",
        "parameters": [
          {
            "name": "entryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      },
      "patch": {
        "tags": [
          "blocklist-entries"
        ],
        "summary": "Set or clear why a blocklist entry is blocked.",
        "description": "Body `{ \"reason\": \"...\" }`, at most 200 characters; `null` or blank clears it. `reason` is\nrequired. Requires `WriteAccess`. An entry outside the workspace is `not_found`.",
        "operationId": "blocklist-entries.update",
        "parameters": [
          {
            "name": "entryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBlocklistEntryRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBlocklistEntryRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBlocklistEntryRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistEntryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistEntryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistEntryModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocklist-entries/imports": {
      "post": {
        "tags": [
          "blocklist-entries"
        ],
        "summary": "Import blocklist rows from a CSV file.",
        "description": "Multipart field `file` is a `.csv` with `email` and/or `domain` columns and an optional\n`reason` column; a cell over 200 characters is cut, never failing the file. Optional form field\n`reason` (at most 200 characters) applies to every row without its own. Rows already on the blocklist keep\ntheir own reason, and a shared mail provider in the `domain` column (gmail.com) is skipped. Requires\n`WriteAccess`.",
        "operationId": "blocklist-entries.import",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "reason": {
                    "type": "string"
                  }
                }
              },
              "encoding": {
                "file": {
                  "style": "form"
                },
                "reason": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistImportModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistImportModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistImportModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/blocklist-rules": {
      "get": {
        "tags": [
          "blocklist-rules"
        ],
        "summary": "List blocklist rules.",
        "description": "Every rule in `position` order (at most 20), each with `stages`, `accountTypes`,\n`crmLifecycles`, `crmList` (with the `members` and `readAt` of its last read) and\n`matches`: the accounts its stages (and release window, `releaseAfterDays`) or account types match now\n(each once), the domains and people (emails) it blocks and the CRM records it matches, enabled or not. The first\nenabled rule that matches a domain or email gives its entry the reason. Requires `ReadAccess`.\n\nNeeds the `blocklist_rules` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "blocklist-rules.list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBlocklistRuleModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBlocklistRuleModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBlocklistRuleModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "blocklist_rules"
        ]
      },
      "post": {
        "tags": [
          "blocklist-rules"
        ],
        "summary": "Create a blocklist rule.",
        "description": "Body: `name` (1-100), `stages` (up to 20 keys from `GET /v1/opportunity-stages`, none archived,\nelse `400 out_of_range`), `accountTypes` (account types to match: `client`, `lost`,\n`churned`, `partner`, `competitor`, `investor`, `do_not_contact`; never\n`prospect`), `reason` (1-200, goes on every entry the rule adds), `enabled` (default true) and\n`releaseAfterDays` (1-3650, default none: an account matched by stage comes off that many days after its deal\nin the stages closed; a deal with no close date and a match by type never release), `crmLifecycles` (up to 5\nof `lead`, `prospect`, `opportunity`, `customer`, `churned`: CRM records in those stages)\nand `crmListId` (a contact or company list of the connected CRM, at most 10,000 members). The CRM criteria\nbind the workspace's connected CRM (`crmConnectionId`) and fail as on the preview (`not_enabled`,\n`invalid_state`, `unsupported`, `out_of_range`, `503`, `429`). A rule needs at least one\nstage, account type, CRM lifecycle stage or a CRM list (`400 validation_failed` otherwise); it matches an\naccount with a live opportunity in one of its stages or whose type is one of its account types, and the CRM records\nin its lifecycle stages or on its list. The rule goes last and its list is read right away. An enabled rule's\ndomains and people are on the blocklist when this returns; a domain or email any entry already lists keeps that\nentry, and a free email domain is never blocked. A workspace's 21st rule is `409 conflict`. Returns\n`201`. Requires workspace settings access.\n\nNeeds the `blocklist_rules` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "blocklist-rules.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlocklistRuleBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlocklistRuleBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBlocklistRuleBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRuleModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRuleModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRuleModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "blocklist_rules"
        ]
      }
    },
    "/v1/blocklist-rules/preview": {
      "get": {
        "tags": [
          "blocklist-rules"
        ],
        "summary": "Preview what a blocklist rule would block.",
        "description": "`stages` is a comma-separated list of up to 20 stage keys from `GET /v1/opportunity-stages`; an unknown\n            or archived key is `400 out_of_range`. `accountTypes` is a comma-separated list of account types\n            (`client`, `lost`, `churned`, `partner`, `competitor`, `investor`,\n            `do_not_contact`; `prospect` or an unknown type is `400 out_of_range`). Send at least one of the\n            two, or a CRM criterion: `crmLifecycles` is a comma-separated list of up to 5 CRM lifecycle stages\n            (`lead`, `prospect`, `opportunity`, `customer`, `churned`) and `crmListId` a\n            contact or company list of the connected CRM (`GET /v1/crm-connections/{connectionId}/lists`, at most 10,000\n            members, read live now and never stored). A CRM criterion while `blocklist_rules_crm` is off is\n            `400 not_enabled`; with no connected CRM `400 invalid_state`; on a CRM Kenso cannot read lists or lifecycle\n            stages from `400 unsupported`; an unknown or too large list `400 out_of_range`; a CRM that is not\n            reachable or rate limited `503` or `429`. Returns the accounts with a live opportunity in one of the\n            stages or of one of the types (each once), the distinct domains and people (emails) a rule would block, the CRM\n            records it matches (`crmRecords`), how many of the domains and people a blocklist entry already lists\n            (`alreadyBlocked`, any source), up to 10 accounts by id with one of their domains, up to 10 CRM records with\n            the email or domain each blocks (`crmSample`), and what is left out: accounts and CRM companies with no\n            domain, CRM contacts with neither a company domain nor an email (`skipped.noEmail`) and free email domains.\n            Optional `releaseAfterDays` (1-3650) previews a release window: an account matched by stage counts only while\n            one of its deals in the stages closed less than that many days ago or has no close date (a match by type or from\n            the CRM never releases), and `skipped.released` counts the accounts it already let go. Never writes. Requires\n            `ReadAccess` (accounts view), since it names accounts.\n\nNeeds the `blocklist_rules` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "blocklist-rules.preview",
        "parameters": [
          {
            "name": "Stages",
            "in": "query",
            "description": "Comma-separated stage keys from `GET /v1/opportunity-stages`, up to 20.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "AccountTypes",
            "in": "query",
            "description": "Comma-separated account types (DEV-4105): client, lost, churned, partner, competitor, investor, do_not_contact.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ReleaseAfterDays",
            "in": "query",
            "description": "1 to 3650: previews a release window on the stage matches (DEV-4359).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "CrmListId",
            "in": "query",
            "description": "A contact or company list of the connected CRM (DEV-4027), from `GET /v1/crm-connections/{connectionId}/lists`;\nread live, never stored.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CrmLifecycles",
            "in": "query",
            "description": "Comma-separated CRM lifecycle stages (DEV-4027), up to 5: lead, prospect, opportunity, customer, churned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRulePreviewModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRulePreviewModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRulePreviewModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "blocklist_rules"
        ]
      }
    },
    "/v1/blocklist-rules/{ruleId}": {
      "patch": {
        "tags": [
          "blocklist-rules"
        ],
        "summary": "Update a blocklist rule.",
        "description": "Any of `name`, `stages`, `accountTypes`, `reason`, `enabled`, `position` (0-based;\npast the last rule moves it last, and the rest renumber), `releaseAfterDays` (1-3650, or null so the rule\nnever releases), `crmLifecycles` and `crmListId` (null clears the list; a new list is read right away).\nAbsent fields stay; only `releaseAfterDays` and `crmListId` can be null. `stages`,\n`accountTypes` or `crmLifecycles` may be `[]` while the rule keeps another criterion. Setting a CRM\ncriterion binds the connected CRM and fails as on create; clearing both clears `crmConnectionId`. The\nblocklist follows right away: entries no enabled rule matches any more come off, and entries whose first matching\nrule changed take its reason. Another workspace's rule is `404`. Requires workspace settings access.\n\nNeeds the `blocklist_rules` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "blocklist-rules.update",
        "parameters": [
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBlocklistRuleBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBlocklistRuleBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBlocklistRuleBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRuleModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRuleModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBlocklistRuleModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "blocklist_rules"
        ]
      },
      "delete": {
        "tags": [
          "blocklist-rules"
        ],
        "summary": "Delete a blocklist rule.",
        "description": "Soft delete; the rest renumber. Entries only this rule matched come off the blocklist right away. Returns\n`204`. Another workspace's rule is `404`. Requires workspace settings access.\n\nNeeds the `blocklist_rules` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "blocklist-rules.delete",
        "parameters": [
          {
            "name": "ruleId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "blocklist_rules"
        ]
      }
    },
    "/v1/booking-links": {
      "post": {
        "tags": [
          "booking-links"
        ],
        "summary": "Make a booking link.",
        "description": "Body <c>{ kind, personId?, meetingTypeId?, hostMemberId?, accountId?, campaignId?, stepOrder?, touchId?, assetId?,\nsource?, channel?, senderAddress?, availability? }</c>. `kind: person` needs `personId` and returns the person's one link\nfor that campaign (or Studio page, or source and host): `201` when made, `200` when it already existed. Its\nURL opens the page prefilled (`?k=`). `kind: single_use` returns a new `/s/` link that books once and\nexpires after 30 days; `meetingTypeId` defaults to the host's default type. Email and LinkedIn links never use a\nKenso domain; `senderAddress` sends a campaign email's link to `cal.<sending domain>`. `availability`\n(DEV-3935, single-use only; `400` on a person link) is the Scheduler link's own schedule, in the shape and rules\nof the member default on `/v1/me/calendar-preferences`: its slots use it instead of the meeting type's and the\nhost's, with busy time, notice, window, buffers and the daily cap still on top. Returns\n`{ id, url, kind, expiresAt, availability }` (availability null when none was sent; `id` is what\n`PATCH /v1/booking-links/{bookingLinkId}` takes). 409 `invalid_state` when no\nScheduler domain can serve the link yet or the meeting type is off. Requires Calendar view; another member's page or\ntype also needs the members feature.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "booking-links.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBookingLinkBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBookingLinkBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBookingLinkBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkModel"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      },
      "get": {
        "tags": [
          "booking-links"
        ],
        "summary": "List your open single-use Scheduler links.",
        "description": "DEV-3936. The single-use links the caller made in this workspace that can still book: not used, not expired, and\ntheir meeting type not deleted. A team type's link belongs to the member who made it, so admins also see only their\nown. Newest first. Each item is `{ id, kind, meetingTypeId, personId, createdAt, expiresAt, availability }`\n(availability null when the link uses its meeting type's times). There is no `url`: only a hash of the token\nis stored, so a link's URL is shown once, by `POST /v1/booking-links`. `limit` 1-200 (default 50),\n`cursor` from `pagination.nextCursor`. Needs the scheduler feature and the Calendar page (view).\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "booking-links.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBookingLinkSummaryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBookingLinkSummaryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBookingLinkSummaryModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/booking-links/{bookingLinkId}": {
      "patch": {
        "tags": [
          "booking-links"
        ],
        "summary": "Change a single-use Scheduler link's times.",
        "description": "DEV-3936. Body `{ availability }`: the link's own schedule in the shape and rules of the create body (it may\nhave no weekly times, such as only date overrides with ranges), or `null` to go back to the meeting type's\ntimes. Omitted: unchanged. Only the member who made the link changes it: another member's link, a person link and a\nlink in another workspace are 404. A used or expired link is 409 `invalid_state` (`link_used`,\n`link_expired`). Returns the link as `GET /v1/booking-links` lists it. Needs the scheduler feature and the\nCalendar page (view).\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "booking-links.update",
        "parameters": [
          {
            "name": "bookingLinkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBookingLinkBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBookingLinkBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateBookingLinkBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkSummaryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkSummaryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLinkSummaryModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/booking-links/suggested-times": {
      "get": {
        "tags": [
          "booking-links"
        ],
        "summary": "Up to three open times on the person's own booking link, each a link that opens with the time picked.",
        "description": "Query `personId` (required), `meetingTypeId?`, `hostMemberId?`, `campaignId?`, `senderAddress?`. The page is\n`hostMemberId`'s (default: the caller; another member's needs the members feature) and the type one of that member's\nown (default: their default type). The times are the first open slot of each of the next days that have one (at most three, 14 days, host's zone),\nfor the member the page routes the person to. Each time's `url` opens the page with that time picked; opening never\nbooks. A member on Calendly, Cal.com or HubSpot gets `status: external_tool` and that link, with no times.\n`campaignId` is the campaign of the thread being answered (404 when it is not this workspace's): a booking through the\nlink counts for it. `senderAddress` is the mailbox the reply goes out from (400 when it is not an email address): with a\ncampaign, the link lands on cal.<sending domain> when that host is ready. A client seat creates nothing: it gets times only on\na link it already has for this person, else 409 `invalid_state`.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "booking-links.suggested-times",
        "parameters": [
          {
            "name": "PersonId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "MeetingTypeId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "HostMemberId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "SenderAddress",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSuggestedTimesModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSuggestedTimesModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSuggestedTimesModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/bookings/bulk-reassign": {
      "post": {
        "tags": [
          "bookings"
        ],
        "summary": "Reassign a former member's upcoming bookings.",
        "description": "Body `{ hostMemberId, cursor? }`. Moves each of the next 20 upcoming bookings of a member who left to a free member at the\nsame time (account owner, campaign sender, the type's team, then anyone with a meeting type on); the new host's calendar sends the\ninvite and the old event is cancelled from the former member's calendar. Returns <c>{ succeeded, failed, results, hasMore,\nnextCursor }</c>; each result has `bookingId`, `status` (reassigned, already_handled, no_free_member, host_busy,\ncalendar_write_failed, failed), `startAt`, `newBookingId`, `hostMemberId`, `calendarEventRemoved` and, on a\nfailure, `error`. Send `nextCursor` back as `cursor` while `hasMore`. 403 without the members feature;\n409 invalid_state while the person is still a member.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "bookings.bulk-reassign",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingLeaverRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingLeaverRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BookingLeaverRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLeaverResultModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLeaverResultModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLeaverResultModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/bookings/bulk-cancel": {
      "post": {
        "tags": [
          "bookings"
        ],
        "summary": "Cancel a former member's upcoming bookings.",
        "description": "Body `{ hostMemberId, cursor? }`. For each of the next 20 upcoming bookings of a member who left, removes the event from their\ncalendar and cancels the booking as a workspace cancel. Same answer shape as bulk-reassign; `status` is cancelled,\nalready_handled, host_busy, calendar_write_failed or failed. The calendar tells the booker only when `calendarEventRemoved`\nis true. A cancelled booking whose invite stayed on the former member's calendar has `errorCode: booker_not_told` and an\n`error`, and counts in `failed`: tell the booker yourself. 403 without the members feature; 409 invalid_state while\nthe person is still a member.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "bookings.bulk-cancel",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingLeaverRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BookingLeaverRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BookingLeaverRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLeaverResultModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLeaverResultModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingLeaverResultModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/bookings": {
      "get": {
        "tags": [
          "bookings"
        ],
        "summary": "List bookings.",
        "description": "Ordered by start, then id. Filters: `hostMemberId` and `organizerMemberId` (both narrow the bookings the\ncaller sees); `status` (confirmed, rescheduled, cancelled or no_show,\ncomma = OR); `startAfter` (start at or after) and `startBefore` (start before); `campaignId`,\n`personId` and `accountId`. `limit` 1-200 (default 50), `cursor` from\n`pagination.nextCursor`. Needs the scheduler feature and the Calendar page (view).\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "bookings.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "HostMemberId",
            "in": "query",
            "description": "Only bookings this member hosts.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "OrganizerMemberId",
            "in": "query",
            "description": "Only bookings this member organizes. Narrows what the caller sees, never widens it.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "description": "confirmed, rescheduled, cancelled or no_show; comma = OR.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "StartAfter",
            "in": "query",
            "description": "Start at or after.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "StartBefore",
            "in": "query",
            "description": "Start before.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "PersonId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "AccountId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBookingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBookingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfBookingModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/bookings/{bookingId}": {
      "get": {
        "tags": [
          "bookings"
        ],
        "summary": "Get a booking.",
        "description": "404 for a booking in another workspace or one the caller cannot see.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "bookings.get",
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/bookings/{bookingId}/no-show": {
      "post": {
        "tags": [
          "bookings"
        ],
        "summary": "Mark a booking as a no-show.",
        "description": "The host, the organizer or an admin who can see the booking marks a confirmed booking whose start has passed. Logs\nmeeting.no_show on the meeting timeline and puts a \"Sorry we missed you\" draft with a fresh single-use link in Today for\napproval. Marking it again answers 200 and changes nothing. 404 for a booking in another workspace, one the caller cannot\nsee (as on GET) or one the caller may not mark. 409 invalid_state before the start or for a cancelled or rescheduled\nbooking. Needs the scheduler feature and the Calendar page (view).\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "bookings.no-show",
        "parameters": [
          {
            "name": "bookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBookingModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/brands/by-host": {
      "get": {
        "tags": [
          "brands"
        ],
        "summary": "Return the brand of a verified custom host.",
        "description": "`host` is a hostname such as `app.agency.com` (no scheme or port), matched\n            case-insensitively. Returns the product name, logo, favicon (Kenso defaults where the brand has\n            none), and the Auth0 organization to log in with. Cacheable for 60 seconds.",
        "operationId": "brands.get-by-host",
        "parameters": [
          {
            "name": "host",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBrandByHostModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBrandByHostModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBrandByHostModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/bug-reports": {
      "post": {
        "tags": [
          "bug-reports"
        ],
        "summary": "File a bug report.",
        "description": "`multipart/form-data`. `description` (required, 1-10000 characters) is the user's own words, filed\n            verbatim. `source` (required) is `app_form`, `support_chat`, `ken_agent` or `mcp`.\n            Optional: `title` (120; else the first line of the description, cut to 80), `summary` (10000, an\n            agent-written summary with steps to reproduce), `clientName` (100, the MCP client), `pageUrl` (2000),\n            `userAgent` (500), `diagnostics` (20000, JSON text), `transcript` (60000, plain text),\n            `supportAttachmentIds` (repeated, at most 5 of the caller's own support chat attachments) and `files`\n            (repeated, at most 10 files of 25 MB each; programs and scripts are refused, such as .exe, .js, .sh, .py, .html,\n            .svg, disk images like .iso and macro Office files like .xlsm). Each report\n            is a new issue in Kenso's Linear Alerts project with every file uploaded into it; the reporter never sees a Linear\n            id or URL. Answers `202``{ status: received }`. A bad field is `400` naming it, a file or request\n            that is too large `413`. Each report takes one unit of the caller's daily limit (20) and the workspace's (50):\n            past either, `429``quota_exceeded` with `Retry-After` and `quotaResetAt`. `503` when\n            Linear is not configured or refused a file or the issue; nothing is filed then. Any workspace member, Client seats\n            included.\n\nNeeds the `bug_reports` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "bug-reports.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "Description": {
                    "type": "string",
                    "description": "Required, 1-10000 characters. The user's own words, filed verbatim."
                  },
                  "Title": {
                    "type": "string",
                    "description": "At most 120 characters. Absent: the first line of `description`, cut to 80 characters."
                  },
                  "Summary": {
                    "type": "string",
                    "description": "At most 10000 characters. An agent-written summary: steps to reproduce, expected and actual."
                  },
                  "Source": {
                    "type": "string",
                    "description": "Required: `app_form`, `support_chat`, `ken_agent` or `mcp`."
                  },
                  "ClientName": {
                    "type": "string",
                    "description": "At most 100 characters. The MCP client's name (Claude, ChatGPT, Cursor...)."
                  },
                  "PageUrl": {
                    "type": "string",
                    "description": "At most 2000 characters. The page the user was on."
                  },
                  "UserAgent": {
                    "type": "string",
                    "description": "At most 500 characters. The browser's user agent."
                  },
                  "Diagnostics": {
                    "type": "string",
                    "description": "At most 20000 characters of JSON text, pretty-printed in the issue when it parses."
                  },
                  "Transcript": {
                    "type": "string",
                    "description": "At most 60000 characters of plain text, one turn per paragraph (`User: ...` / `Assistant: ...`)."
                  },
                  "SupportAttachmentIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Repeated, at most 5: 32-hex support chat attachment ids the caller uploaded."
                  },
                  "Files": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "Repeated, at most 10 files of at most 25 MB (26,214,400 bytes) each. Programs and scripts are refused by extension;\na file with no extension is accepted."
                  }
                }
              },
              "encoding": {
                "Description": {
                  "style": "form"
                },
                "Title": {
                  "style": "form"
                },
                "Summary": {
                  "style": "form"
                },
                "Source": {
                  "style": "form"
                },
                "ClientName": {
                  "style": "form"
                },
                "PageUrl": {
                  "style": "form"
                },
                "UserAgent": {
                  "style": "form"
                },
                "Diagnostics": {
                  "style": "form"
                },
                "Transcript": {
                  "style": "form"
                },
                "SupportAttachmentIds": {
                  "style": "form"
                },
                "Files": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBugReportReceiptModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBugReportReceiptModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBugReportReceiptModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "413": {
            "description": "Content Too Large",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "bug_reports"
        ]
      }
    },
    "/v1/calling/calls": {
      "post": {
        "tags": [
          "calling"
        ],
        "summary": "Call a person from the browser.",
        "description": "Body `{ personId, toNumber?, fromNumberId?, callTaskId?, touchId?, recording? }`. `toNumber` must be one\nof the person's phones (400 `invalid_phone`); absent, Kenso calls their primary phone. `fromNumberId` absent\ntakes the member's number, else the workspace's first. `callTaskId` must be an open call task of the person\n(400). `touchId` must be a call touch of the person (400; 404 when there is none), and the call's outcome\ncloses it; send `callTaskId` or `touchId`, not both (400).\nKenso rings the member's browser first (log in with `POST /v1/calling/tokens`) and dials the person when the\nbrowser answers; `status` is `ringing_rep`. Kenso holds 10 minutes at `millicreditsPerMinute` and\ncharges started minutes when the call ends. A refused call is 422 `call_refused` with the reason in\n`details[0].code` (`outside_calling_hours`, `opted_out`, `no_phone`, ...) and, for the\ntime-bound reasons, `nextAllowedAt`. 402 `insufficient_credits`, `calling_limit_reached` (the monthly\ncalling spend limit) or `member_credit_limit_reached`; 404 for a person of another workspace; 503\n`provider_unavailable` when the carrier is not set up or does not take the call (nothing is charged), 503\n`try_again` with `Retry-After` when another call of the workspace is starting. Requires edit on the\nAccounts page.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.calls-create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StartCallRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/StartCallRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/StartCallRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingCallModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingCallModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingCallModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/calls/{callId}/hangup": {
      "post": {
        "tags": [
          "calling"
        ],
        "summary": "Hang up a browser call.",
        "description": "Hangs up every leg of the call that is still up and answers 202 with its status; the call ends when the carrier\nconfirms. A call that already ended answers 200 with its final status. Only the member who placed the call may hang\nit up (403); a call of another workspace, or one not placed in Kenso, is 404. Requires edit on the Accounts page.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.calls-hangup",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingHangupModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingHangupModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingHangupModel"
                }
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingHangupModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingHangupModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingHangupModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/calls/{callId}/voicemail-drop": {
      "post": {
        "tags": [
          "calling"
        ],
        "summary": "Drop a voicemail greeting on a browser call.",
        "description": "Body `{ voicemailId? }`: one of your greetings, absent your oldest. The call must be one you placed that the\nother side answered, with a `voicemailDropMode` other than `off`. Kenso waits for the voicemail's beep,\nhangs up your side, plays the greeting and then hangs up; the call is logged with the `voicemail`\ndisposition. When detection heard no machine (`amdResult``human` or `not_sure`) no beep comes, so\na drop you ask for plays at once: ask after the beep you hear. Answers 202 with `voicemailDropStatus` (`requested`, `starting`, `playing` or\n`failed`), 200 once it is `dropped`; asking again while a drop is under way answers its state. Do not\nhang up the call yourself after a drop: that ends the greeting. 409 `invalid_state` for a call that ended,\nwas not answered or has drops off, 409 `no_voicemail` when you named none and have none, 404 for a greeting\nthat is not yours, 403 for a call you did not place, 503 `provider_unavailable` when the audio store or the\ncarrier is not set up. Requires edit on the Accounts page.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.calls-voicemail-drop",
        "parameters": [
          {
            "name": "callId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DropVoicemailRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DropVoicemailRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DropVoicemailRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailDropModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailDropModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailDropModel"
                }
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailDropModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailDropModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailDropModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/tokens": {
      "post": {
        "tags": [
          "calling"
        ],
        "summary": "Create a WebRTC login token for the member's browser.",
        "description": "Returns `{ token, sipUsername, expiresAt }` on the member's own carrier credential; the browser logs in with it\nto answer the calls it starts. The token is a secret: keep it in memory. 422 `call_refused`\n(`calling_disabled`) while calling is off, 503 `provider_unavailable` when the carrier is not set up or not\nreachable. Requires edit on the Accounts page.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.tokens-create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingTokenModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingTokenModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingTokenModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/settings": {
      "get": {
        "tags": [
          "calling"
        ],
        "summary": "Return the workspace's calling settings.",
        "description": "A workspace that never saved them gets the defaults and `updatedAt` null. Requires `ReadAccess`.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.settings-get",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSettingsModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      },
      "patch": {
        "tags": [
          "calling"
        ],
        "summary": "Update the workspace's calling settings.",
        "description": "Absent fields stay unchanged; null is not allowed. `consentNotice` is `auto`, `always` or\n`never`; `voicemailDropMode` is `off`, `manual` or `auto`; `allowedCountries` is a\nnon-empty list of `US` and `CA`. `voicemailToMobile: true` needs `acceptTcpaNotice: true` in\nthe same body (400 `validation_failed` on `acceptTcpaNotice` otherwise), which records who accepted and\nwhen; turning it off keeps that record. Requires the `workspace_settings` feature.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.settings-update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSettingsModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/numbers": {
      "get": {
        "tags": [
          "calling"
        ],
        "summary": "List the workspace's phone numbers.",
        "description": "Every number not released, newest first, at most five. `unpaid` is true when its monthly credits could not\nbe charged. Requires `ReadAccess`.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.numbers-list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCallingNumberModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCallingNumberModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCallingNumberModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      },
      "post": {
        "tags": [
          "calling"
        ],
        "summary": "Buy a phone number.",
        "description": "Buys a local number for 100 credits a month; the first month is charged when it is active. `e164` is a\nnumber from `numbers/available`: when a fresh search no longer offers it, the first number that search\noffers is bought. `assignedMemberId` must be an active member without a number (400 `invalid_member`,\n409 `member_already_has_number`); `cnam` is at most 15 letters, digits, spaces and `.,&-`, US\nnumbers only. 409 `number_limit_reached` at five numbers, 402 when the workspace cannot pay the first\nmonth, 409 `no_numbers_available` when the search finds none, 503 `provider_unavailable` when the\ncarrier is not set up or refuses the order (nothing is charged). `status` is `ordering` while the\ncarrier has not assigned the number. Toll-free numbers are not sold. Requires the `workspace_settings` and\n`billing` features: a number is a monthly charge.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.numbers-buy",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BuyCallingNumberRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BuyCallingNumberRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BuyCallingNumberRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/numbers/available": {
      "get": {
        "tags": [
          "calling"
        ],
        "summary": "Search local numbers for sale.",
        "description": "Up to 10 local numbers in `country` (`US` or `CA`, and one the workspace calls), optionally in a\nthree-digit `areaCode` or a `locality`. Each costs `monthlyCredits` credits a month once bought.\n503 `provider_unavailable` when the carrier is not set up or not reachable. Requires the\n`workspace_settings` feature.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.numbers-available",
        "parameters": [
          {
            "name": "Country",
            "in": "query",
            "description": "ISO 3166 alpha-2 country, `US` or `CA`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "AreaCode",
            "in": "query",
            "description": "Three-digit area code.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Locality",
            "in": "query",
            "description": "City name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAvailableCallingNumberModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAvailableCallingNumberModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfAvailableCallingNumberModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/numbers/{numberId}": {
      "patch": {
        "tags": [
          "calling"
        ],
        "summary": "Assign a phone number or set its caller name.",
        "description": "Absent fields stay unchanged. `assignedMemberId` null unassigns it; a member must be active in the\nworkspace (400 `invalid_member`) and hold no other number (409 `member_already_has_number`).\n`cnam` null clears it; at most 15 letters, digits, spaces and `.,&-`, US numbers only. A caller name\nchange goes to the carrier first (503 `provider_unavailable` when it does not take it). A number of another\nworkspace is 404 `not_found`. Requires the `workspace_settings` feature.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.numbers-update",
        "parameters": [
          {
            "name": "numberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      },
      "delete": {
        "tags": [
          "calling"
        ],
        "summary": "Release a phone number.",
        "description": "Stops its monthly credits (the paid month is not refunded) and gives it back to the carrier. Returns the number\n`released` (also when the carrier no longer has it or never assigned it), or `202` with\n`status: releasing` when the carrier has not taken it back yet: the number stays `releasing` and\nfinishes by itself once the number lifecycle job is on; until then the client may retry `DELETE`. A number\nof another workspace is 404 `not_found`. Requires the `workspace_settings` and `billing` features,\nlike the buy.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.numbers-release",
        "parameters": [
          {
            "name": "numberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingNumberModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/rates": {
      "get": {
        "tags": [
          "calling"
        ],
        "summary": "Return what a call to a number costs.",
        "description": "`to` is the number to call. `millicreditsPerMinute` is the destination rate plus the rep's leg, and\n            `recordingMillicreditsPerMinute` is added when the call is recorded. A destination Kenso has no price for yet\n            is `priced: false` with null rates; a value that is not a phone number is 400 `invalid_phone`.\n            Requires `ReadAccess`.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.rates-get",
        "parameters": [
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingRateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingRateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingRateModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/spend-limit": {
      "get": {
        "tags": [
          "calling"
        ],
        "summary": "Return the workspace's monthly calling spend limit.",
        "description": "`monthlyLimitMillicredits` null is no limit; a workspace that never set it reads 2,000,000 (2,000 credits)\n            with `isDefault: true`. `spentThisMonthMillicredits` is call minutes and recordings charged this UTC\n            calendar month plus open call holds, the same spend the cap counts; number fees are not in it. Separate from\n            `/v1/spend-limits`. Requires `ReadAccess`.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.spend-limit-get",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSpendLimitModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSpendLimitModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSpendLimitModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      },
      "patch": {
        "tags": [
          "calling"
        ],
        "summary": "Set the workspace's monthly calling spend limit.",
        "description": "Body `{ \"monthlyLimitMillicredits\": number | null }`: null is no limit, else 1 to 100,000,000 (400\n`validation_failed` otherwise). The next call reads it. Returns the GET shape. Requires the\n`workspace_settings` and `billing` features.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.spend-limit-update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSpendLimitModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSpendLimitModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingSpendLimitModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/voicemails": {
      "get": {
        "tags": [
          "calling"
        ],
        "summary": "List your voicemail greetings.",
        "description": "Your live greetings, oldest first: the first is the one an `auto` drop plays. `audioUrl` is a 5-minute\nlink to listen to it, absent while Kenso's audio store is not set up. Requires `ReadAccess`.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.voicemails-list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCallingVoicemailModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCallingVoicemailModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCallingVoicemailModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      },
      "post": {
        "tags": [
          "calling"
        ],
        "summary": "Upload a voicemail greeting.",
        "description": "`multipart/form-data` with `file` (a WAV or MP3 recording, at most 12 MiB and 60 seconds) and an optional\n            `name` (at most 80 characters, blank is `Voicemail`). Kenso reads the format from the audio itself. 400\n            `validation_failed` on `file` with `unsupported_audio` (WebM, Ogg and anything else),\n            `unreadable_audio`, `too_long` or `invalid`; 409 `voicemail_limit_reached` at five greetings;\n            503 `provider_unavailable` while Kenso's audio store is not set up. Bulk rate-limit class, like the other\n            uploads. Requires edit on the Accounts page.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.voicemails-create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary"
                  },
                  "name": {
                    "type": "string"
                  }
                }
              },
              "encoding": {
                "file": {
                  "style": "form"
                },
                "name": {
                  "style": "form"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCallingVoicemailModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/calling/voicemails/{voicemailId}": {
      "delete": {
        "tags": [
          "calling"
        ],
        "summary": "Delete a voicemail greeting.",
        "description": "Deletes one of your greetings and its audio; a drop that has not played it yet fails. 404 for a greeting that is\nnot yours or is already deleted. Requires edit on the Accounts page.\n\nNeeds the `calling` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "calling.voicemails-delete",
        "parameters": [
          {
            "name": "voicemailId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "x-ken-features": [
          "calling"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/compliance": {
      "get": {
        "tags": [
          "campaign-compliance"
        ],
        "summary": "Read the campaign's consent-first countries and their acknowledgements.",
        "description": "`countries` lists each country the campaign's live contacts sit in whose cold email rules launch asks someone to\n            acknowledge, most contacts first: `iso2`, `name`, `regime` (`opt_out`, `consent` or\n            `unresolved`), `note`, `sources`, `contactCount`, and `acknowledgedAt` and\n            `acknowledgedByUserId` once someone acknowledged it. `acknowledgementRequired` is true while any country\n            has no acknowledgement: launch then answers 409 `acknowledgement_required` and launch readiness lists\n            `acknowledgement_required`. Requires the Campaigns page.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-compliance.get",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignComplianceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignComplianceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignComplianceModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/compliance/acknowledgements": {
      "post": {
        "tags": [
          "campaign-compliance"
        ],
        "summary": "Acknowledge the cold email rules of the campaign's consent-first countries.",
        "description": "Body `{ \"countries\": [\"ES\"] }`: ISO-2 codes of countries the read lists. Records the caller and the time for\neach, which lets launch proceed for that country. A country already acknowledged keeps its first acknowledgement,\nso a repeat is harmless. Answers 200 with the campaign's compliance, as the read does. An empty list\n(`required`), an unknown code (`unknown_country`), and a country the read does not list\n(`not_required`) are 400 `validation_failed`, and nothing is recorded. Requires Campaigns edit.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-compliance.acknowledge",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AcknowledgeComplianceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/AcknowledgeComplianceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/AcknowledgeComplianceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignComplianceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignComplianceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignComplianceModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/images": {
      "get": {
        "tags": [
          "campaign-images"
        ],
        "summary": "Current images of some leads of a campaign: each image variable's and the lead's own custom_image.",
        "description": "`contactIds` (required) is 1 to 200 comma-separated contact ids. `variableKey` keeps one key: an image\n            variable's key, or `custom_image` for the lead's own image; an unknown key is an empty list. One item per lead\n            and key that has an image, any status, ordered by `contactId` then `variableKey`; an image of a deleted\n            variable is left out. `status` is `pending`, `ready` or `failed`; a failed image carries\n            `errorCode` and `errorDetail`. A ready image carries `previewUrl`, which works until\n            `previewExpiresAt` (1 hour). One page: `hasMore` is always false. Requires the Campaigns page.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-images.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "contactIds",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "variableKey",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignImageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignImageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignImageModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaign-images/{imageKey}": {
      "get": {
        "tags": [
          "campaign-images"
        ],
        "summary": "One image with a fresh preview URL (1 hour).",
        "description": "`imageKey` is the image's 26-character key from the list. A ready image carries `previewUrl`, which works\n            until `previewExpiresAt` (1 hour); call again for a new one. An unknown or malformed key is 404. Requires the\n            Campaigns page.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-images.get",
        "parameters": [
          {
            "name": "imageKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignImageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignImageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignImageModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/languages": {
      "get": {
        "tags": [
          "campaign-languages"
        ],
        "summary": "Read a campaign's languages.",
        "description": "The five language settings as the campaign carries them (`sourceLanguage`, `languageMode``source_only` or `auto`, `enabledLanguages`, `formalityOverrides`, `languageFallback``source` or `hold`; change them with PATCH /v1/campaigns/{campaignId}). `available`: every market pack\nthe campaign can enable, by locale, with its name in its own language and `status``supported` or\n`tested`. `mix`: the campaign's contacts that can still be contacted (live, not do-not-contact) per outreach\nlanguage, most contacts first; `lowConfidence` of a locale's `contacts` are under the routing confidence\nfloor and get the source language. `unresolved`: contacts with no outreach language yet. Requires the Campaigns\npage.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-languages.get",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLanguagesModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLanguagesModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLanguagesModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/localizations": {
      "get": {
        "tags": [
          "campaign-localizations"
        ],
        "summary": "List the campaign's localized steps.",
        "description": "One item per live email or LinkedIn step and language, email first, then by step order, variant and language.\n`language` keeps one locale (any casing); `stepId` keeps the rows of the email or LinkedIn step with that\nid; `channel` (`email` or `linkedin`) keeps one channel's rows, and picks one when an email and a\nLinkedIn step share an id. `stale` is true when the row is marked stale, or was written from older step text or\nan older market pack: generate it again. `generating` is true while the localization job has it queued.\n`status` is `draft`, `approved`, `stale`, `needs_review` or `failed`. One page:\n`hasMore` is always false. Requires the Campaigns page.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-localizations.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Language",
            "in": "query",
            "description": "One locale, such as `fr-FR`, in any casing.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "StepId",
            "in": "query",
            "description": "One email or LinkedIn step id. An email and a LinkedIn step can share an id: add `channel` to pick one.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Channel",
            "in": "query",
            "description": "`email` or `linkedin`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignLocalizationModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignLocalizationModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignLocalizationModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      },
      "post": {
        "tags": [
          "campaign-localizations"
        ],
        "summary": "Queue the writing of the campaign's localized steps.",
        "description": "Body `{ \"languages\": [\"fr-FR\"], \"stepIds\": [11], \"channel\": \"email\" }`, all optional: absent or empty means\nevery language the campaign enables and every active email or LinkedIn step with text (not a Studio step, not an AI\nconnection note). `channel` keeps one channel's steps, and picks one when an email and a LinkedIn step share an id.\nA missing localization is created as a draft; a stale, failed or needs-review one, and one written from older step\ntext or an older market pack, is queued again. A current draft or approved localization, and one already queued,\nstay as they are. A localization a person edited is queued again only when `stepIds` names its step, so a new\nmarket pack never rewrites a person's text unasked. Answers 202 with every localization of the campaign, as the list\ndoes; the localization job writes the queued ones (`generating` true until it does). A language the campaign\ndoes not enable, a campaign with none, and a step with no text to localize are 400 `validation_failed`. While\nthe localization job is not on for the workspace, nothing is queued: 409 `invalid_state` with detail\n`localization_disabled`. Requires Campaigns edit.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-localizations.generate",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateLocalizationsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateLocalizationsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateLocalizationsRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignLocalizationModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignLocalizationModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignLocalizationModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/localizations/{localizationId}/approve": {
      "post": {
        "tags": [
          "campaign-localizations"
        ],
        "summary": "Approve a localized step for sending.",
        "description": "Only a current draft that passed its quality check is approved: its rules passed, and its judge score reached the\nmarket pack's threshold (a localization a person edited is approved on the rules alone). Otherwise 409\n`localization_not_approvable`, with `details[].code``not_draft`, `stale` (written from older\nstep text or an older market pack: generate it again), `qa_failed` or `score_below_threshold`. While the\nlocalization job has it queued, 409 `localization_generating`. Records the caller as the approver (none for an\nAPI key with no user) and the time. `channel` (`email` or `linkedin`) is needed only when an email and\na LinkedIn localization of the campaign share the id (400 `channel_required` otherwise). Requires Campaigns\nedit.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-localizations.approve",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "localizationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/localizations/{localizationId}/regenerate": {
      "post": {
        "tags": [
          "campaign-localizations"
        ],
        "summary": "Write a localized step again.",
        "description": "Body `{ \"instruction\": \"Shorter, and less formal.\" }`, optional (up to 2,000 characters): the localization job\nrewrites the current text with it, or writes it anew without one. The localization becomes a draft (an approval is\nwithdrawn, so a live campaign stops sending it: contacts routed to it are held or get the source text, as the\ncampaign's language fallback says, until it is approved again) and `generating` is true until the job has\nwritten it. This rewrites text a person edited. Answers\n202 with the localization. While the job has it queued, 409 `localization_generating`. A language the campaign\nno longer enables and a step with no text are 400 `validation_failed`. While the localization job is not on\nfor the workspace, 409 `invalid_state` with detail `localization_disabled`. `channel` as for approve.\nRequires Campaigns edit.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-localizations.regenerate",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "localizationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegenerateLocalizationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RegenerateLocalizationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RegenerateLocalizationRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/localizations/{localizationId}": {
      "patch": {
        "tags": [
          "campaign-localizations"
        ],
        "summary": "Edit a localized step's text.",
        "description": "Body `{ \"subjectLine\": \"...\", \"bodyContent\": \"...\" }`; send one or both (a LinkedIn localization has no\nsubject). The text is stored as sent, with the unsubscribe link text set to the market pack's, and checked by the\nrules with no model call: `qaReport` holds their result. `editedByHuman` becomes true and the localization\na draft (an approval is withdrawn, so a live campaign stops sending it until it is approved again, as for\nregenerate); the English mirror and the judge score stay as they were, for the text before the edit. An edited\ndraft whose rules pass can be approved. While the localization job has it queued, 409\n`localization_generating`. A blank body, and a blank subject for a step that has one, are 400\n`validation_failed`. While campaign images are on for the workspace, an email text with image tokens a sequence\nsave would refuse (more than two, one in the subject or in a handwritten letter, or one not on its own line or in\nits own paragraph) is 400 `validation_failed` with the sequence save's message, and nothing is stored.\n`channel` as for approve. Requires Campaigns edit.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaign-localizations.update",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "localizationId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "channel",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocalizationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocalizationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLocalizationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignLocalizationModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/campaigns": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "List campaigns in the current workspace.",
        "description": "Includes archived campaigns and excludes approval-test drafts.\nOptional `status` is a comma-separated OR filter. `q` is a case-insensitive\nsubstring of the name, or of the owner's first name, last name, full name, or email.\nOptional `kind` is `sales` or `recruiting`.\nEach item carries `leadCount`, from one cached count of the workspace. It usually lags new or removed leads\nby under 15 minutes; on a very large workspace the first list after a quiet period can show an older count, which\nthe next list corrects. A campaign that count has not seen is counted live, and a single-campaign read\n(`GET /v1/campaigns/{campaignId}`) counts live for a current number. `leadCount` is omitted when that\ncount does not finish in time on a very large workspace.\nOrdered by id. Read-only. Requires `ReadAccess`.",
        "operationId": "campaigns.list",
        "parameters": [
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Kind",
            "in": "query",
            "description": "DEV-1274: sales or recruiting; omit for both.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Create a campaign in the current workspace.",
        "description": "Returns `201` and `Location`. Requires `ReadAccess`, matching the legacy create.\nReserves the `campaignCreate` abuse quota. A sales campaign starts with `stopCompanyOnReply` on.\nOptional `kind` is `sales` (default) or `recruiting`. A recruiting campaign needs the\n`recruiting` flag for the workspace, else `400 validation_failed` with detail code\n`feature_disabled`; it starts with `stopCompanyOnReply`, `groupSameCompanySends` and same-company\nCc off, and as a Draft, so its AI build can start. Optional `roleId` names a live role of the workspace\n(else `404 not_found`) and is only for a recruiting campaign (else `400` with detail code\n`not_recruiting`).",
        "operationId": "campaigns.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Return one campaign in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Read-only. Requires `ReadAccess`.",
        "operationId": "campaigns.get",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "campaigns"
        ],
        "summary": "Update a campaign's name, contact limit, send schedule, ramp-up, owner, sending switches, same-company\nrules, account-play protection, new-leads-first order, language settings, mode, or auto-launch.",
        "description": "Absent fields stay unchanged. `status` is rejected. Unknown JSON members are a 400.\nA schedule or daily-cap change writes a planner request row (nothing consumes it since DEV-1821;\ngap-fill picks up the change on its next pass); `rampUpDays`,\n`stopCompanyOnReply` and `groupSameCompanySends` do not, as in the legacy update.\n`rampUpDays` is 0 (no ramp) to 30 scheduled sending days, else `400 validation_failed`.\n`stopCompanyOnReply` is the same stored value as `stopSequenceForCompanyOnReply` in the\nLinkedIn settings; it is written after the other fields.\n`ownerMemberId` must be an active member of the workspace, else `400 validation_failed`\nwith detail code `not_a_member`. Changing `stopOnReply`, `trackClicks`,\n`trackOpens`, or `unsubscribeLink` needs the `campaign_send_settings` flag for\nthe workspace, else `400 validation_failed` with detail code `feature_disabled` per\nfield and nothing is written. Sending the stored value is accepted without the flag.\n`protectAccountPlays` turns skipping people in active account plays on or off for this\ncampaign; people already stopped stay stopped. Requires `WriteAccess`.\n`newLeadsFirst` true gives first emails the campaign's daily capacity ahead of its follow-ups; it takes\neffect on the next gap-fill pass. While it is true the response carries `awaitingFirstEmailCount`.\n`bookingMeetingTypeId` names a live, enabled round robin meeting type of this workspace that\ntakes this campaign's bookings when the account owner and the sender can't; `null` clears it.\n`kind` cannot be changed: any value is `400 validation_failed` with detail code\n`kind_immutable`. `roleId` names a live role of this workspace for a recruiting campaign and needs\nthe `recruiting` flag; `null` clears it. On a sales campaign it is `400` with detail code\n`not_recruiting`.\n`excludedCountries` replaces the countries this campaign never sends to: ISO 3166-1 alpha-2 codes or\ncountry names, stored as upper-case codes; `[]` clears it. An entry that names no country is\n`400 validation_failed` with detail code `invalid_country` and nothing is written. Imports drop a contact\nwhose country is listed and the sequencer skips one already on the campaign, from its next pass.\nThe language settings (`sourceLanguage`, `languageMode``source_only` or `auto`,\n`enabledLanguages`, `formalityOverrides` locale to `formal` or `informal`, and\n`languageFallback``source` or `hold`) need the `multilingual_outreach` flag for the\nworkspace, else `400 validation_failed` with detail code `feature_disabled` per field sent, even for the\nstored value. A locale must be a market pack that is not a draft and `sourceLanguage` may also be a language\nwith a primary pack (`en`), else detail code `unknown_language` or `draft_language`; any other bad\nvalue is `invalid_value`. `null`, `[]` or `{}` clears `enabledLanguages` or\n`formalityOverrides`.\n`mode` is `batch` or `trigger`, else `400 validation_failed`. Batch to trigger converts the\ncampaign to signal-based sending; trigger to batch is `400 validation_failed` with detail code\n`mode_one_way` and nothing is written. `autoLaunchWhenReady` true launches the campaign once it is\nready, with no further confirmation; changing it needs the launch permission (`403 forbidden`), is\n`400` once the campaign launched or for a trigger or approval-test campaign, and `409 conflict` once\nauto-launch has run. `mode``trigger` on a batch campaign is `400 validation_failed` on\n`autoLaunchWhenReady`, and nothing is written, when it comes with `autoLaunchWhenReady` true, or\nwithout it while the campaign is set to auto-launch: send `false` in the same request to turn that off.",
        "operationId": "campaigns.update",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCampaignRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCampaignRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCampaignRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "campaigns"
        ],
        "summary": "Soft-delete a campaign.",
        "description": "Requires `ReadAccess`, matching the legacy delete. Returns `204`.",
        "operationId": "campaigns.delete",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/launch": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Launch sending for a campaign.",
        "description": "Requires `WriteAccess`. Returns the campaign after the launch command confirms. While the\nworkspace's data is scheduled for deletion or being deleted, returns `409 invalid_state`.",
        "operationId": "campaigns.launch",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/archive": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Archive a campaign.",
        "description": "Idempotent for an already-archived campaign. A campaign that is still sending returns\n`409 invalid_state`. Requires `WriteAccess`.",
        "operationId": "campaigns.archive",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/duplicate": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Duplicate a campaign inside the current workspace.",
        "description": "`includeContacts` copies contacts. The copy stays in this workspace.\n            Returns `201` and `Location`. Requires `WriteAccess`.\n            Reserves the campaign-duplicate abuse quota.",
        "operationId": "campaigns.duplicate",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DuplicateCampaignBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/DuplicateCampaignBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/DuplicateCampaignBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/pause": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Pause sending, processing, and AI workflows together.",
        "description": "Idempotent. A campaign that is already paused returns `200` with the unchanged resource.\nA subsystem that is not running is left as it is. If any subsystem fails, the action returns\nthat error and the caller can retry. A campaign that is still launching returns\n`409 invalid_state`. Requires `WriteAccess`.",
        "operationId": "campaigns.pause",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/resume": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Resume sending, processing, and AI workflows together.",
        "description": "Idempotent. A campaign that is already running returns `200` with the resource.\nA subsystem that was not paused is left as it is. If any subsystem fails, the action returns\nthat error and the caller can retry. A campaign that is still launching returns\n`409 invalid_state`, and so does every campaign while the workspace's data is scheduled for\ndeletion or being deleted. Requires `WriteAccess`.",
        "operationId": "campaigns.resume",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/launch-readiness": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Report whether a campaign can launch and how long sending should take.",
        "description": "Replaces `GET /v1/campaigns/{id}/can-launch` and\n`GET /v1/campaigns/{id}/sending-estimate`. A campaign outside the workspace is\n`not_found` before either read. Requires `ReadAccess`. `warnings` never change\n`canLaunch`; `localization_incomplete` (one per enabled language of an `auto` campaign)\nnames the steps with no approved translation and whether those contacts get the source text or are held.\n`approval_required` means the client was asked and launch answers 409 `approval_required` until they\napprove; its `kinds` lists what waits (`copy`, `lead_list`, ...). The warning\n`approval_will_be_requested` names what nobody asked about yet: launch asks the client, then refuses until they approve.",
        "operationId": "campaigns.get-launch-readiness",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLaunchReadinessModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLaunchReadinessModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLaunchReadinessModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/workflow-readiness": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Report whether a campaign's workflows can start.",
        "description": "Replaces `startWorkflowReadiness` on the legacy `GET /v1/campaigns/{id}`. Runs the same\nchecks that gate starting enrichment, verification, and AI workflows (imported contacts or an\nactive signal, contact limit, name, schedule, email sequence, AI variables) and returns each one\nwith `isPassed`. Sending launch readiness is `GET .../launch-readiness`. A campaign\noutside the workspace is `not_found`. Read-only. Requires `ReadAccess`.",
        "operationId": "campaigns.get-workflow-readiness",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkflowReadinessModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkflowReadinessModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkflowReadinessModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/mail-providers": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Count a campaign's contacts by email security gateway and mailbox host.",
        "description": "Each live contact is judged by its first Safe or Verified email, the one the lead list shows.\n`gateways` lists every active security gateway and `mailboxProviders` every active mailbox host\nand forwarder, 0 included, most contacts first. `pendingCount` counts contacts whose domain is not\nchecked for a gateway yet. Counts cover at most 100,000 contacts (`isPartial`). Read-only. A campaign\noutside the workspace, or a workspace without the `security_gateways` feature, is `not_found`.\nRequires `ReadAccess`.\n\nNeeds the `security_gateways` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "campaigns.get-mail-providers",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignMailProvidersModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignMailProvidersModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignMailProvidersModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "security_gateways"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/weekly-report": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Return one campaign's weekly report.",
        "description": "`weekOf` is any date (`YYYY-MM-DD`, from 2000-01-01 to one year from today) in the\n            wanted Monday-to-Sunday week. `timeZone` is an IANA name; without it the campaign's sending\n            time zone is used, else UTC. The week's dates are picked in that time zone; its numbers and\n            `changed` are counted on those UTC days, like the Analytics tab. Without `weekOf` the\n            report covers the latest week that has ended both there and in UTC. `week` and\n            `toDate` are email counts from campaign performance. `toDate` and `segments` run\n            from the campaign's creation (at most 366 days back) to the end of the week. `changed` and\n            `next` are sentences built from data, not AI. `next` is as of the request, in the\n            campaign's sending time zone, and is empty for a week older than the default week. A missing or cross-workspace campaign is\n            `not_found`. Read-only. Requires `ReadAccess`.",
        "operationId": "campaigns.get-weekly-report",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "weekOf",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "timeZone",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignWeeklyReportModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignWeeklyReportModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignWeeklyReportModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/inboxes": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "List inboxes assigned to a campaign.",
        "description": "Requires `ReadAccess`. A campaign outside the workspace is `not_found`.",
        "operationId": "campaigns.list-inboxes",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "campaigns"
        ],
        "summary": "Replace the inboxes assigned to a campaign.",
        "description": "Full replace. Send `inboxIds`, or `assignAllActive` to assign every Kenso-sendable inbox. Either one\nfixes the pool to that list. `allInboxes: true` turns on live \"All inboxes\" instead: every inbox a launch\nwould assign (paused inboxes the campaign lacks and blocked Migma senders left out) joins now and inboxes\nconnected later join too; it ignores the other fields and needs the `sender_routing` flag for the\nworkspace, else `400 validation_failed` with detail code `feature_disabled`.\nRequires `WriteAccess`. A campaign outside the workspace is `not_found` before the write.",
        "operationId": "campaigns.replace-inboxes",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignInboxesRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignInboxesRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignInboxesRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/linkedin-accounts": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "List LinkedIn accounts assigned to a campaign.",
        "description": "Requires `ReadAccess`. A campaign outside the workspace is `not_found`.",
        "operationId": "campaigns.list-linkedin-accounts",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "campaigns"
        ],
        "summary": "Replace the LinkedIn accounts assigned to a campaign.",
        "description": "Full replace. Send `linkedinAccountIds`, or `assignAllConnected` to assign every\nConnected LinkedIn seat. Requires `WriteAccess`. A campaign outside the workspace is\n`not_found` before the write.",
        "operationId": "campaigns.replace-linkedin-accounts",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignLinkedInAccountsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignLinkedInAccountsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignLinkedInAccountsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/linkedin-settings": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Read a campaign's LinkedIn settings.",
        "description": "Replaces `GET /v1/campaigns/{id}/linkedin-config`. A campaign outside the workspace\nis `not_found`. Requires `ReadAccess`.",
        "operationId": "campaigns.get-linkedin-settings",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSettingsModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "campaigns"
        ],
        "summary": "Replace a campaign's LinkedIn settings.",
        "description": "`channelPolicy` is `linkedin_only`, `linkedin_first_email_fallback`,\n            `email_first_linkedin_reinforce`, or `parallel`. Requires Campaigns edit access (owners, admins and editors by default).\n            A campaign outside the workspace is `not_found` before the write.",
        "operationId": "campaigns.replace-linkedin-settings",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSettingsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSettingsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSettingsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSettingsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/scoring": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Read whether lead scoring is enabled for a campaign.",
        "description": "Replaces `POST /v1/campaigns/{id}/scoring` for reads. A campaign outside the workspace\nis `not_found`. Requires `ReadAccess`.",
        "operationId": "campaigns.get-scoring",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScoringSettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScoringSettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScoringSettingsModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "campaigns"
        ],
        "summary": "Turn lead scoring on or off for a campaign.",
        "description": "Requires `WriteAccess`. A campaign outside the workspace is `not_found` before the write.",
        "operationId": "campaigns.replace-scoring",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceScoringSettingsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceScoringSettingsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceScoringSettingsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScoringSettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScoringSettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScoringSettingsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/ai-workflows": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "List the AI workflows attached to a campaign.",
        "description": "Ids: 1 qualification, 2 personalization, 3 rewriting, 4 segmentation, 6 scoring, 8 line check.\nRead-only. Requires `ReadAccess`. A campaign outside the workspace is `not_found`.",
        "operationId": "campaigns.list-ai-workflows",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignAiWorkflowModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignAiWorkflowModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignAiWorkflowModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "campaigns"
        ],
        "summary": "Replace the AI workflows attached to a campaign.",
        "description": "Full replace: send every workflow id the campaign should run in `aiWorkflowIds`.\nIds not listed are detached, and an empty list detaches all of them. Read the current set\nfirst to add one workflow. Ids: 1 qualification, 2 personalization, 3 rewriting,\n4 segmentation, 6 scoring, 8 line check. Rewriting runs only when the campaign has rewriting prompts.\nLine check (8) grades personalization lines before they are saved and holds a contact whose\nlines fail; a campaign gets it with personalization by default, and detaching it is the opt-out.\nThis route does not add it: keep 8 in the list to keep it on.\nWhile the campaign is scheduled, launching, or sending, 1, 2, and 4 must stay as they are\nand 3 may only be added; any other change to them is `invalid_state` (409) because\nthey gate which contacts may send, so pause first. 6 and 8 can change at any time.\nNo other campaign field changes. Requires `WriteAccess`.\nA campaign outside the workspace is `not_found` before the write.",
        "operationId": "campaigns.replace-ai-workflows",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignAiWorkflowsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignAiWorkflowsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignAiWorkflowsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignAiWorkflowModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignAiWorkflowModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignAiWorkflowModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/scoring/run": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Score contacts in a campaign.",
        "description": "The run finishes in the request and returns a `lead_scoring` job. Poll it with\n`GET /v1/jobs/{jobId}?type=lead_scoring`. Scores are `qualityScore` on each contact.\nRequires `WriteAccess`. A campaign outside the workspace is `not_found` before the run.",
        "operationId": "campaigns.run-scoring",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RunCampaignScoringRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RunCampaignScoringRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RunCampaignScoringRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/enrichment-runs": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Queue lead enrichment for a campaign.",
        "description": "Replaces the legacy campaign enrichment trigger. The request finishes when Search\naccepts the batches and returns an `enrichment` job. `minConfidence` defaults to 0.5.\nRequires `WriteAccess`. A campaign outside the workspace is `not_found` before the run.",
        "operationId": "campaigns.create-enrichment-run",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEnrichmentRunRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEnrichmentRunRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEnrichmentRunRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/retry-enrichment": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Re-queue failed enrichment without restarting the campaign.",
        "description": "Deletes failed website and email-finder markers so existing workers pick the contacts up again.\nDoes not restart processing, and does not change qualification, personalization, or sent state.\nIf data or email enrichment is paused, the markers are still cleared and workers wait until resume.\nIdempotent: clearing nothing is still `200`. An archived campaign is\n`validation_failed` and is not touched. A campaign outside the workspace is\n`not_found` before the retry. Requires `WriteAccess`.",
        "operationId": "campaigns.retry-enrichment",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRetryEnrichmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRetryEnrichmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRetryEnrichmentModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/restart": {
      "post": {
        "tags": [
          "campaigns"
        ],
        "summary": "Restart a campaign's processing.",
        "description": "Re-runs the processing pipeline from the beginning, to recover a campaign that stalled or errored, or to\nreprocess after a configuration change. On a draft campaign it starts processing behind the same readiness checks\nas `resume`, and a draft trigger campaign is `400 validation_failed` (start it with `resume`).\nAn archived campaign is `400 validation_failed`. A campaign with `autoLaunchWhenReady` launches once\nprocessing reaches ready. Returns the campaign. Requires `WriteAccess` and the launch permission. While the\nworkspace's data is scheduled for deletion or being deleted, returns `409 invalid_state`.",
        "operationId": "campaigns.restart",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/sender-routing": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Return a campaign's sender routing.",
        "description": "DEV-5225. `allInboxes` is the campaign's inbox mode. Each rule sends the first email to prospects on its\nmailbox provider or security gateway only from its domains and inboxes; a gateway rule wins over a mailbox\nprovider rule, and prospects no rule matches go from the inboxes no rule claims (`everyoneElse`). Per rule and\nfor Everyone else: the campaign's inboxes that can send now (Kenso-sendable, not paused), their summed daily limits,\nand the leads that can still get an email and match now (at most 100,000 leads read; a lead whose provider is still\nbeing detected is in no group). `warnings`: `rule_no_inbox`, `everyone_else_no_inbox`,\n`rule_slow` (over 5 days at the rule's capacity). Read-only. Needs the workspace's `sender_routing` flag,\nelse `400 validation_failed` with detail code `feature_disabled`. Requires `ReadAccess`. A\ncampaign outside the workspace is `not_found`.",
        "operationId": "campaigns.get-sender-routing",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSenderRoutingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSenderRoutingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSenderRoutingModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "campaigns"
        ],
        "summary": "Replace a campaign's sender routing rules.",
        "description": "DEV-5225. Full replace: `rules` is every rule, `[]` clears them. Each rule names an active mailbox\nprovider or security gateway `provider` slug (one rule per provider) and at least one whole sending domain in\n`domains` (lowercased when saved; inboxes added on it later join) or single `inboxIds`. Every domain must\nbe the address domain of a workspace inbox and every inbox a workspace inbox, else `400 validation_failed`\nwith detail codes `unknown_provider`, `unsupported_provider`, `duplicate_provider`,\n`empty_rule`, `unknown_domain` or `unknown_inbox`. Applies to first emails planned from now on and to\nqueued first emails at send time; follow-ups stay on the first email's inbox. Returns the routing as `GET`\ndoes. Needs the `sender_routing` flag (`feature_disabled`). Requires `WriteAccess`. A campaign\noutside the workspace is `not_found` before the write.",
        "operationId": "campaigns.replace-sender-routing",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignSenderRoutingRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignSenderRoutingRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCampaignSenderRoutingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSenderRoutingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSenderRoutingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSenderRoutingModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/recipient-providers": {
      "get": {
        "tags": [
          "campaigns"
        ],
        "summary": "Count a campaign's leads by mailbox provider and security gateway.",
        "description": "DEV-5225. Every active mailbox provider and security gateway with the campaign's leads behind it (0 included),\nmost leads first: the leads that can still get an email, by the domain of the address they are sent to. A lead\ncounts once under its mailbox provider and once under its security gateway. `pendingCount`: provider still\nbeing detected. `noProviderCount`: no listed provider. Counts cover at most 100,000 leads (`isPartial`).\nRead-only. Needs the `sender_routing` flag (`feature_disabled`). Requires `ReadAccess`. A campaign\noutside the workspace is `not_found`.",
        "operationId": "campaigns.list-recipient-providers",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRecipientProviderCountsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRecipientProviderCountsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfRecipientProviderCountsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/cli/logins": {
      "post": {
        "tags": [
          "cli-logins"
        ],
        "summary": "Start a CLI login.",
        "description": "No credential. `deviceName` (1 to 100 characters) is shown on the approval page. Returns the\n`loginId` to poll `POST /v1/cli/logins/token` with (keep it private), the `userCode` to show, the\n`verificationUrl` to open, `expiresIn` seconds and the poll `interval` in seconds.",
        "operationId": "cli-logins.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCliLoginRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCliLoginRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCliLoginRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCliLoginCreatedModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCliLoginCreatedModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCliLoginCreatedModel"
                }
              }
            }
          },
          "429": {
            "description": "Too many logins started from this IP address."
          }
        }
      }
    },
    "/v1/cli/logins/token": {
      "post": {
        "tags": [
          "cli-logins"
        ],
        "summary": "Poll a CLI login for its API key.",
        "description": "No credential: `loginId` is the credential. Once the login is approved, returns the new `apiKey` with\nits `apiKeyId`, the chosen `workspaceId`, the approver's `email` and the key's `expiresAt`,\none time, and deletes the login. Otherwise `400` with `error.code` set to `authorization_pending` (keep\npolling), `slow_down` (polled sooner than `interval`; wait longer), `access_denied` or\n`expired_token` (stop; start a new login).",
        "operationId": "cli-logins.token",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CliLoginTokenRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CliLoginTokenRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CliLoginTokenRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCliLoginTokenModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCliLoginTokenModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCliLoginTokenModel"
                }
              }
            }
          },
          "429": {
            "description": "Too many polls from this IP address."
          }
        }
      }
    },
    "/v1/client-approvals/settings": {
      "get": {
        "tags": [
          "client-approvals"
        ],
        "summary": "Return the workspace's external approval settings.",
        "description": "Rules per kind (`require` or `auto`), reminder emails, the reminder time zone, the portal URL,\nwhen the link was last rotated, the effective \"External approval links\" switch of the white-label\nmaster, and the pending count. The first read creates the settings and the portal link.\nRequires the `workspace_settings` feature, because the portal URL lets its holder approve.\n\nNeeds the `client_approvals` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "client-approvals.get-settings",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfClientApprovalSettingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfClientApprovalSettingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfClientApprovalSettingsModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "client_approvals"
        ]
      }
    },
    "/v1/client-approvals/items": {
      "get": {
        "tags": [
          "client-approvals"
        ],
        "summary": "List external approval items, newest first.",
        "description": "Filters: `status` (pending, approved, changes_requested, superseded, cancelled), `kind`\n(copy, lead_list, reply, order), `campaignId`. `limit` 1-200, default 50.\nRequires workspace membership. Lists only the kinds the caller's pages cover, each at view: replies need\nInbox, copy and lead lists Campaigns, orders Delivery. A `kind` the caller cannot read lists nothing.\n\nNeeds the `client_approvals` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "client-approvals.list-items",
        "parameters": [
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Kind",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfClientApprovalItemModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfClientApprovalItemModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfClientApprovalItemModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "client_approvals"
        ]
      }
    },
    "/v1/client-approvals/items/{itemId}": {
      "get": {
        "tags": [
          "client-approvals"
        ],
        "summary": "Return one external approval item with its snapshot, comments and log.",
        "description": "`snapshot` is what the client reviews, frozen when the item was created (lead removals update\n            it), without a reply's internal `send` block. A missing or cross-workspace id is `not_found`,\n            and so is an item the caller's pages do not cover (replies need Inbox, copy and lead lists Campaigns,\n            orders Delivery, share items Share, each at view). Requires workspace membership.\n\nNeeds the `client_approvals` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "client-approvals.get-item",
        "parameters": [
          {
            "name": "itemId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfClientApprovalItemDetailModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfClientApprovalItemDetailModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfClientApprovalItemDetailModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "client_approvals"
        ]
      }
    },
    "/v1/client-approvals/events": {
      "get": {
        "tags": [
          "client-approvals"
        ],
        "summary": "List the approval log, newest first.",
        "description": "Every item created, decision, comment, lead removal or restore, reminder, link rotation, rules\nchange, campaign pause or resume and submitted Classic review. `itemId` filters to one item.\n`before` is an ISO-8601 upper bound (exclusive). `limit` 1-200, default 50.\nRequires workspace membership. Leaves out the events of items the caller's pages do not cover, as the\nitem list does, share link events without the Share page and classic reviews without Campaigns.\n\nNeeds the `client_approvals` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "client-approvals.list-events",
        "parameters": [
          {
            "name": "ItemId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Before",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfClientApprovalEventModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfClientApprovalEventModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfClientApprovalEventModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "client_approvals"
        ]
      }
    },
    "/v1/companies": {
      "get": {
        "tags": [
          "companies"
        ],
        "summary": "List companies in the current workspace.",
        "description": "Ordered by id. `q` matches the name. `domain` is an exact match. Requires `ReadAccess`.",
        "operationId": "companies.list",
        "parameters": [
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Domain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCompanyModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCompanyModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCompanyModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/companies/{companyId}": {
      "get": {
        "tags": [
          "companies"
        ],
        "summary": "Return one company in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Requires `ReadAccess`.",
        "operationId": "companies.get",
        "parameters": [
          {
            "name": "companyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCompanyModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCompanyModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCompanyModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/company-data": {
      "get": {
        "tags": [
          "company-data"
        ],
        "summary": "Get a company's brand, technologies and funding by domain.",
        "description": "`domain` is the company's website domain or URL (acme.com, https://www.acme.com/about); it is looked up as\n            its registrable domain, and a free email domain is 400 `validation_failed`. `kinds` is a comma-separated\n            subset of `brand`, `technologies` and `funding` (default: all three); an unknown kind is 400.\n            `brand` (name, description, logoUrl) and `funding` (totalFunding, lastRound, rounds newest first, at most\n            20) come from the Kenso Search company that owns the domain. `technologies` (name, categories, lastSeenAt,\n            most recently seen first, at most 200) come from Kenso's archive of the company's website. A kind is absent when it\n            was not asked for or Kenso has nothing for it. Each kind carries `source` (`ken_search`) and\n            `fetchedAt`. `isCompanyFound` is absent when neither brand nor funding was asked for. Free: no credits.\n            An answer with a found company or technologies counts one row of the workspace's `searchBrowseRows`\n            quota; past it, 429 `quota_exceeded` with `Retry-After`. Kenso Search unavailable is 503. Requires the\n            Search page.",
        "operationId": "company-data.get",
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kinds",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCompanyDataModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCompanyDataModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCompanyDataModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contact-exports": {
      "post": {
        "tags": [
          "contact-exports"
        ],
        "summary": "Create a contact export and return its job.",
        "description": "`kind` is `contacts` (workspace filters), `campaign`, `clicked`,\n            `advanced`, or `events`. Campaign kinds require `campaignId` in the current\n            workspace. `events` also requires `occurredAfter` and `occurredBefore`.\n            Requires `ExportAccess`. Poll `GET /v1/jobs/{jobId}?type=contact_export`.\n            The job's `downloadUrl` streams the file.\n            Contacts from a Kenso library list are never exported. For kinds `contacts`, `campaign` and\n            `advanced` the job's `excludedLibraryContacts` says how many were left out, including 0.\n            Kind `contacts` also takes `campaignIds` (1 to 50 campaigns of the workspace, not with `campaignId`),\n            `listId` (a contact's import list), `createdAfter` (inclusive) and `createdBefore` (exclusive),\n            `maxRows` (1 to 50000) and `skipRows` (in contact id order). Other kinds refuse them.\n            `readyOnly` still needs one `campaignId`.",
        "operationId": "contact-exports.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactExportBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contact-exports/{exportId}/content": {
      "get": {
        "tags": [
          "contact-exports"
        ],
        "summary": "Download a contact export file.",
        "description": "Streams CSV, or a ZIP when a campaign export is one file per segment.\nEach download is sized from a live count and charged to the export row quota before any row is read;\na file over the per-request row cap is `429 quota_exceeded`.\nRequires `ExportAccess`. A missing or expired export is `not_found`.",
        "operationId": "contact-exports.content",
        "parameters": [
          {
            "name": "exportId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/csv": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "application/zip": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contact-fields": {
      "get": {
        "tags": [
          "contact-fields"
        ],
        "summary": "List contact fields for the column picker, CSV export, and CSV import.",
        "description": "The catalog is static. `usages` is `list`, `export`, and/or `import`.\nOrdered with `qualityReasoning` beside `qualityScore`. `securityGateway` and\n`mailboxProvider` are listed only when the workspace has security gateways. `customImage` (an import\ntarget) is listed only when the workspace has campaign images. Requires `ReadAccess`.",
        "operationId": "contact-fields.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactFieldModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactFieldModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactFieldModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contact-imports/buyer-previews": {
      "post": {
        "tags": [
          "contact-imports"
        ],
        "summary": "Preview the buyers Ken finds at a list of companies, for a campaign's ICP.",
        "description": "Body: `campaignId` (required; another workspace's campaign is `404`), `companies` (1 to 50, each\n`{ key?, name?, domain? }` with a name or a domain, else `400 validation_failed` on\n`companies[i]`) and `perCompany` (1 to 3, default 3). Send a longer list in parts of 50. Example:\n`{ \"campaignId\": 812, \"companies\": [{ \"key\": \"row-2\", \"name\": \"Northwind\", \"domain\": \"northwind.com\" }], \"perCompany\": 3 }`.\nA company with a domain is the Kenso Search company that owns it: one Kenso Search also matches by the given name at\nthat domain, else one whose website is the domain's home page. A company with only a page under the domain\n(`notion.so/...`) does not count, and no name match stands in for it. A company without a domain is found by\na name only one company has. Unmatched companies say why (`acme.com is not in Kenso Search`,\n`could not match notion.so: no company in Kenso Search has it as its own website`,\n`no domain, name matches 3 companies`). A matched company lists up to `perCompany` people at it in the\ncampaign's ICP (the titles, seniority, functions and exclusions of its live segments), best first, each with a\none-line `reason`, and each person once in the whole answer, by Kenso id or LinkedIn URL (Kenso Search can hold\none person twice); when the ICP finds too few, Ken fills the\ncompany from a looser search and marks those people `weakMatch`. No ICP ranks people by seniority, and\n`icp` is empty. `signal` is the company's latest hiring, funding or leadership change from the last 90\ndays. A company Kenso Search does not answer for in time is `failed`; retry it. Each person's `contact`\nis a `POST /v1/contact-imports``source: search` contact: post the kept ones unchanged to add them\n(dedupe, blocklist and lead credits apply there). Nothing is stored and nothing is charged; the companies times\n`perCompany` count against the workspace's `searchBrowseRows` quota (`429 quota_exceeded` past\nit). Requires `WriteAccess` and the Import feature.\n\nNeeds the `csv_buyer_preview` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "contact-imports.buyer-preview",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBuyerPreviewRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBuyerPreviewRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateBuyerPreviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBuyerPreviewModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBuyerPreviewModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfBuyerPreviewModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "csv_buyer_preview"
        ]
      }
    },
    "/v1/contact-imports": {
      "post": {
        "tags": [
          "contact-imports"
        ],
        "summary": "Start a contact import and return its job.",
        "description": "JSON `source` is `campaign` (copy from `sourceCampaignId`), `search`\n(a `contacts` array, at most 1,000), `blitz` (the same `contacts` array, at most 1,000, for people\npicked in the Blitz tab of Search; the run's surface is Blitz and it counts no Kenso Search work) or `people` (`personIds`, 1 to 1,000 workspace\npeople; each becomes a contact with their name, email, title, LinkedIn URL and the company of their\nhighest-priority account; needs the `accounts` feature and Accounts view, and with account scope\n`own` takes only people on the caller's accounts), `event` (`eventId`, optional `roles`\nand `includeAccounts`: an outbound event's attendees with an email or a LinkedIn URL, at most 5,000; rows\nwhose company is a workspace account are left out unless `includeAccounts` is true, and then with account\nscope `own` only those on the caller's accounts are added; needs the `accounts` and\n`event_outbound` features and Accounts view) or `sales_navigator` (`linkedinAccountId`, a seat\nthe caller connected, and `url`, a Sales Navigator lead search or lead list; its people with their name,\ncurrent title, LinkedIn profile and company. One import reads at most 8 pages (about 200 to 400 people): a\nlist it cannot read to the end imports nothing and is `400 validation_failed` with code\n`incomplete_read` on `url`. Behind the `sales_navigator` feature, a seat without Sales\nNavigator is `409 sales_navigator_required`). Where the `linkedin_network` feature is on,\n`linkedin_connections` (`connectionIds`, 1 to 1,000 ids from `GET /v1/linkedin-connections`;\neach becomes a contact with first and last name, title, headline, LinkedIn URL, seniority and Kenso Search's\ncompany name, domain, LinkedIn URL, industry and size; needs Accounts view; elsewhere it is an unknown\nsource). Multipart `source=csv` uploads a\nCSV file into `campaignId`; its optional form field `columnMappings` (a JSON array of mappings, as for a\nGoogle Sheet) sets the columns, and a mapped column the header row lacks is `400 validation_failed`; omitted,\nthe header row is mapped by the import's aliases. Its optional form field `emailsFoundByKen=true` (staff only, otherwise\n`403 forbidden`) stamps every imported email `found_by_ken`, so the cross-workspace Kenso DB lookup\nmay serve it. Behind the `csv_import_check` feature (a field sent while it is off is\n`400 validation_failed` on that field) the CSV create also takes the List check choices of a scan: `fixes`\n(a JSON array of `missingKey`, `invalidEmail`, `noMx`, `catchAll`, `personalEmail`,\n`roleAddress`, `companyContacted`, `companyCap`) drops the rows the List check flags for them and\ncounts each under its key in the job's `skipped`; `includeRecentlyContacted=true` keeps the rows the\ncampaign's recently-emailed window would skip, for this import only; `cleanup=true` cleans the name, email,\ntitle, company, domain, LinkedIn URL and phone cells as the scan's cleanup notes say. Omitted, they are off.\nJSON `source``google_sheets` (behind the `google_sheets`\nflag) reads `spreadsheetId` (an id or a Google Sheets URL) and the optional `sheet` with the\ncaller's own Kenso Workspace Google connection; row 1 is the header and `columnMappings` work as for a CSV.\nNo connection is `409 reconnect_required`; a sheet not picked for Kenso is `409 sheet_not_shared`.\nJSON `source``airtable` (behind the `airtable` flag) reads every record of `tableId` (an id\nor name) in `baseId`, or of its `viewId` when set, with the workspace's Airtable token: the table's\nfield names, primary field first, are the header and each record is a row of cell text. A table or view of\nmore than 10,000 records is `400 validation_failed` on `tableId`: import it in parts through views.\nNo token is `409 not_connected`; a token without the read scopes or access to the base is\n`409 scope_required`.\nJSON `source``saved_list` (behind the `saved_lists` flag; elsewhere it is an unknown source)\nimports the members of `savedListId`: a list of this workspace (a private one only for its owner), a list\nshared with it, or a library list. The optional `memberFilters` (`country`, `seniority`,\n`title`, `industry`, `headcountBand`, `hasSendableEmail`) narrow the members. A company\nlist with `roles` (1 to 20 titles) imports up to 5 people per company found by Kenso Search, for at most 500\ncompanies; without `roles` each company is one company contact. `findPeople` must be absent or false.\nMembers this list already put in the campaign are skipped, so a retry adds only the rest. A library list's\ncached Safe emails land Safe with no email charge on a paid plan; a Free workspace gets no emails from a library\nlist. A member copied out of a library list follows the same rules in any list. `columnMappings` is refused:\nthe list sets its own columns. More than 100,000 contacts is `400 validation_failed` on `memberFilters`.\nEvery source applies the import's dedupe, blocklist and contact\nlimits. A JSON body over 10 MB is `413`; the multipart CSV upload accepts up to 400 MB.\nRequires `WriteAccess`. Poll `GET /v1/jobs/{jobId}?type=contact_import`.\n`linkedin_url` (`url`, optional `linkedinAccountId`, `maxLeads`, `postKinds`) queues a\nLinkedIn import that needs the `linkedin_url_import` flag.\nOptions (DEV-15): `source=campaign` takes `importLimit` (above 0), `importOffset` (0 or more),\n`onlyImportQualifiedContacts`, `onlyImportValidContacts`, `deduplicateCampaignIds` (1 to 50 campaigns of\nthe workspace; others are `not_found`), `deduplicationMode` (`none`, `by_email` the default, or\n`by_data`), `allowReimport`, `copyDataEnrichment` and `copyEmailEnrichment` (keep the source's\nenrichment results; default false). `source=search` (not `blitz`) takes `importLimit`, `triggerPostProcessing`\n(default true) and `tagIds` (1 to 50 workspace contact tags put on every imported contact). A multipart CSV takes\nthe form fields `importLimit` and `tagIds` (a JSON array, for example `[3,4]`). An option sent with a\nsource that does not honor it, or with `target=people`, is `400 validation_failed` on that field.\n`source=segment` copies one segment of the workspace (`sourceSegmentId`, from any campaign) into\n`campaignId` as a new segment with the source segment's name. `copyQualification`,\n`copyEmailEnrichment` and `copyEmailVerification` keep the source contacts' AI qualification, found\nemails and email verification (each default false). `segmentId` is refused (the copy makes its own\nsegment); a segment name already in the campaign is `400`, and another import into it in progress is\n`409`.\n`target` is `campaign` (the default) or `people`. With `people` (behind the `lead_intake`\nfeature, `404` when off, and Accounts edit) `campaignId` is optional and ignored: the rows of source\n`csv` (multipart, form field `target=people`), `search`, `blitz`, `event`, `linkedin_connections`,\n`sales_navigator`, `google_sheets` or `airtable` are queued and run through person intake as\nworkspace people with source `import`. A row needs an email, a LinkedIn URL, or a name with a business company\ndomain; others are skipped. The job's `personImport` reports the created, updated and skipped counts.",
        "operationId": "contact-imports.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactImportBody"
              }
            },
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/CreateContactImportFormBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          },
          "413": {
            "description": "Content Too Large",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contact-imports/scans": {
      "post": {
        "tags": [
          "contact-imports"
        ],
        "summary": "Suggest the Kenso field of every column of an import file from its header and sample rows.",
        "description": "Body: `source` (required: `csv`, `google_sheets` or `airtable`), `target`\n(`campaign`, the default, or `people`), `campaignId` (required with target campaign: a campaign of\nthe workspace, else `404`), `headers` (the header row, 1 to 200 names of at most 500 characters) and\n`sampleRows` (up to 200 rows; a short row reads as blanks, extra cells are ignored, each cell at most 2,000\ncharacters). `keys` (optional) holds the key columns of every row for the List check: `rowCount` (data\nrows in the file), `cleanup` (default true: each value first goes through the import's cleaner) and one list\nper mapped key field (`email`, `profileUrl`, `companyDomain`, `companyName`,\n`companyLinkedinUrl`, `firstName`, `lastName`, `fullName`, `title`, `emailValidity`),\nindex-aligned, plus `otherEmails` (each further column mapped to email, up to 10 lists) and\n`otherEmailValidity` (the validity column mapped right after each, null where none). With target campaign\nevery list sent has the same length, 1 to 25,000, and `rowCount` is at least that length (else `400` on\n`keys`); a larger file sends its first 25,000 rows and its check is `truncated`. A scan that sends\n`keys` skips the AI suggestions. Example:\n<c>{ \"source\": \"csv\", \"campaignId\": 42, \"headers\": [\"Full Name\", \"Work contact\"], \"sampleRows\": [[\"Ada Lovelace\",\n\"ada@example.com\"]], \"keys\": { \"rowCount\": 1, \"fullName\": [\"Ada Lovelace\"], \"email\": [\"ada@example.com\"] } }</c>.\nReturns 200 with `columns`, one per header in header order: `index`, `csvColumn`,\n`targetField` (a contact field key such as `email`, `full_name` or `profile_url`,\n`custom_variable` or `skip`), `customVariableName` (only for `custom_variable`),\n`confidence` (`high`: the header names the field or nearly every value is one; `memory`: this\nworkspace mapped the header before; `check`: likely, confirm it; `skip`: not imported), `reason`\n(one short sentence), `samples` (up to 3 distinct values, each at most 120 characters) and `cleanup`\n(what the import's cleanup changes in the sample values, e.g. <c>Cleans 3 of 10 sample values (casing,\nformat)</c>, else null); `listKind` (`company` when no column is a person field and one is a company\nfield, else `people`); and `check`, the List check, with `keys` and target campaign (else null):\n`rows`, `scannedRows`, `truncated`, `cleanupApplied`, `always` (what the import skips\nanyway: `failedValidation`, `missingKey`, `blocklist`, `duplicateInFile`,\n`duplicateInCampaign`, `duplicateInOtherCampaign`, first match wins), `contacted` (rows another\ncampaign emailed inside the campaign's recently-emailed window), `checks` (optional fixes: `invalidEmail`,\n`noMx`, `catchAll`, `personalEmail`, `roleAddress`, `companyContacted`,\n`companyCap`), `rowFlags` (`[rowIndex, mask]`), `noEmailRows`, `baselinePrior`,\n`bounce` (`expected`, `beforeFixes`, `band`), `willAdd`, `companyContactedDays`,\n`companyCap`, `domainsChecked`, `domainsTotal`, `titleMix` and `providerMix`. Samples\ncarry the 1-based data row; `rows` and row indexes are 0-based into the key lists. Kenso's own data only, no\npaid lookup. A field is suggested once, except `email`, `email_validity` and\n`custom_variable`. Target people suggests only the fields a people import stores: `email`,\n`first_name`, `last_name`, `full_name`, `title`, `company_name`, `company_domain`,\n`phone_number` and `profile_url`. Nothing is stored. Behind the\n`csv_import_check` flag (404 when off). Needs campaigns view and the import feature. Each call counts on the\nworkspace's `contactImportScans` quota (30 a minute, 600 an hour, 5,000 a day; past it,\n`429 quota_exceeded` with `Retry-After`).\n\nNeeds the `csv_import_check` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "contact-imports.scan",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactImportScanRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactImportScanRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ContactImportScanRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactImportScanModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactImportScanModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactImportScanModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "csv_import_check"
        ]
      }
    },
    "/v1/contacts/bulk-restore": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Restore up to 1,000 soft-deleted contacts by id, the undo of bulk-delete.",
        "description": "Each contact goes back into the campaign and segment it was deleted from, with its emails and\nfields unchanged. Nothing is charged and no enrichment re-runs. A restored contact is live again,\nso the planner of an active campaign can schedule its next email steps. LinkedIn steps the scheduler\nstopped while the contact was deleted (`suppressed_contact_deleted`) stay stopped. Any\nsoft-deleted contact comes back, a lead the end client removed in a lead-list approval included, and\nthat approval is not updated. `succeeded` lists the ids\nthis call restored and `restored` counts them. Each other id is in `failed` with\n`not_deleted` (the contact is live, nothing changed; `skipped` counts these),\n`not_found` (missing or not in this workspace), or `internal_error` (retry that id).\nA retry is safe: an id an earlier call already restored comes back `not_deleted`.\nRequires campaigns edit, matching bulk-delete.",
        "operationId": "contacts.bulk-restore",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkRestoreContactsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkRestoreContactsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkRestoreContactsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkRestoreResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkRestoreResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkRestoreResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/contacts": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Add up to 1,000 contacts to a campaign.",
        "description": "Uses the existing campaign lead upsert, in batches of 100. Accepted and updated rows\nare succeeded. A later batch can fail without rolling back earlier rows; the upsert is\nsafe to retry. `customImageUrl` sets the lead's own image (an empty string clears it):\na malformed URL fails its row before anything is written, and a refused image (campaign\nimages off for the workspace) fails its row with the contact's id, the contact itself saved.\n`customVariables` is an object of string values merged into the contact's custom variables (a null or empty\nvalue clears that key on an existing contact); a key new to the campaign joins its catalog with AI context off.\nA blank, unusable or reserved key, or more than 50 keys, fails its row before anything is written; a batch that\nwould take the campaign past 50 custom variables fails every row in it. `emailValidity` (optional,\n`safe` for an email you already verified) qualifies a new contact on import in a campaign without AI\nqualification, spending one contact allowance; omitted keeps a stored verdict on an existing email.\nRequires `WriteAccess`. `results` has one item per row in request order: `index`, `status`\n(`created`, `updated`, `skipped` or `failed`), `id` when saved, and for a skipped\nor failed row a `reason` (`duplicate`, `blocklisted`, `already_contacted`,\n`limit_reached`, `invalid_email`, `excluded`, `validation` or `other`) and a\n`message`. A saved row has `sendable`, false when the contact will not send (added unqualified\nwith no contact allowance left, or do-not-contact).",
        "operationId": "contacts.create",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignContactsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignContactsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCampaignContactsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "List contacts in the current workspace.",
        "description": "Ordered by id. Requires `ReadAccess`. Each contact on the page counts one row of the workspace's\n`apiReadRows` quota (DEV-3685); past it, 429 `quota_exceeded` with `Retry-After`.",
        "operationId": "contacts.list",
        "parameters": [
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "CompanyId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "SegmentId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Email",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsQualified",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "DoNotContact",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "CreatedAfter",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "CreatedBefore",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/search": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Search contacts in the current workspace.",
        "description": "Same filters as the list, plus more than one `campaignIds` value,\nlead `filters` groups, `readyOnly`, and `contactIds`.\n`q` is the free-text search. Ordered by id unless `sort` is set,\nin which case the cursor is an offset into that order. No total count.\n`readyOnly` requires exactly one campaign id. `securityGateway` and `mailboxProvider` filter\non the contact's first Safe or Verified email and need security gateways on the workspace (400 otherwise).\nRequires `ReadAccess`.\nPages count on `apiReadRows` like the list.",
        "operationId": "contacts.search",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchContactsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchContactsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SearchContactsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/{contactId}": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "Return one contact in the current workspace.",
        "operationId": "contacts.get",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "contacts"
        ],
        "summary": "Update fields on one contact. Absent fields stay unchanged. Null clears a string.",
        "description": "Requires `WriteAccess`, matching the legacy contact update. `outreachLanguage` (a locale whose language\nhas a market pack or a country entry, such as `fr-FR`, `es-MX` or `de`) sets the language by hand:\nsource `manual`, confidence 1, locked, so no import, enrichment or reply replaces it. Null clears and unlocks it.\n`customVariables` (an object of string or null values) merges into the contact's custom variables with the\ncampaign lead upsert's rules: a string sets a key, null or an empty string removes it, keys not sent stay, and a new\nkey joins the campaign's catalog. Absent leaves the bag unchanged; the object itself cannot be null.\n`customImageUrl` (a public https URL of at most 2048 characters) is the lead's own image, shown in emails as\n`{{custom_image}}`: Kenso downloads and hosts it. Empty or null clears it. It needs campaign images on the\nworkspace; otherwise the update is a 400 `validation_failed`.",
        "operationId": "contacts.update",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateContactBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "contacts"
        ],
        "summary": "Soft-delete one contact.",
        "description": "Requires `WriteAccess`, matching the legacy contact delete.",
        "operationId": "contacts.delete",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/contacts/bulk-delete": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Soft-delete up to 1,000 contacts by id.",
        "description": "Requires `ReadAccess`, matching `POST /v1/leads/bulk-delete`.\nIds outside the workspace are reported in `failed` and are not deleted.",
        "operationId": "contacts.bulk-delete",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteContactsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteContactsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteContactsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/bulk-pause": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Pause the campaign sequence of up to 1,000 contacts by id.",
        "description": "Stops each contact's sequence in its campaign with the stop reason `paused`\n(`sequenceStoppedAt` and `sequenceStopReason` on the contact). This is not\ndo-not-contact: the contact stays in other campaigns. Pending unsent steps of the paused\ncontacts are cancelled. `succeeded` lists the ids that are paused after this call, a lead\nthat was already paused included, so a retry is safe. Each other id is in `failed` with\n`already_stopped` (another stop reason holds it; the first stop wins),\n`do_not_contact`, `not_found` (not in this workspace, deleted, or not in a campaign),\nor `internal_error` (retry that id). Requires campaigns edit and `launch` (pausing stops\nlive sends, as a campaign pause does) and the `pause_leads` feature; without it the route is `404`.\n\nNeeds the `pause_leads` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "contacts.bulk-pause",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkContactSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkContactSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkContactSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "pause_leads"
        ]
      }
    },
    "/v1/contacts/bulk-resume": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Resume the campaign sequence of up to 1,000 paused contacts by id.",
        "description": "Clears the stop only where `sequenceStopReason` is `paused`, then asks the planner to\nplan each affected campaign now. A held LinkedIn step picks up within the hour.\n`succeeded` lists the ids this call resumed. Each other id is in `failed` with\n`not_paused` (no stop, or a stop with another reason, which stays) or `not_found`.\nRequires campaigns edit and `launch`, as bulk-pause. Not behind `pause_leads`: clearing a\npause is always safe, so leads paused before the flag was turned off can still be resumed.",
        "operationId": "contacts.bulk-resume",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkContactSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkContactSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkContactSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/bulk-update": {
      "post": {
        "tags": [
          "contacts"
        ],
        "summary": "Update fields on up to 1,000 contacts in one call.",
        "description": "Each item is a `contactId` plus any fields `PATCH /v1/contacts/{contactId}` accepts,\nwith the same semantics: absent fields stay unchanged, null clears a string. Items run one at a\ntime in request order. A contact outside the workspace is `not_found` and is not written.\nA field error fails only that item. `results` is in request order; `status` is\n`updated`, `not_found`, `validation_failed`, or `failed`. The whole request\nis rejected, with nothing written, when `items` is empty, has more than 1,000 entries, has\nan entry that is not an object or lacks a positive `contactId`, or repeats a `contactId`.\nAn item's `customVariables` merges as on the single update. Requires `WriteAccess`, matching the\nsingle update.",
        "operationId": "contacts.bulk-update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkUpdateContactsBody"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkUpdateResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkUpdateResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfContactBulkUpdateResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/{contactId}/events": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "List events for one contact.",
        "description": "Event ids are the stored event id, which is a string. Requires `ReadAccess`.\nA cursor is valid only with the same `limit` that issued it.",
        "operationId": "contacts.events",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "OccurredAfter",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "OccurredBefore",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactEventModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactEventModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactEventModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/{contactId}/website-pages": {
      "get": {
        "tags": [
          "contacts"
        ],
        "summary": "List every scraped website page of the contact's company.",
        "description": "One entry per distinct page with its markdown and scrape date. `source` is\n`archive` for pages copied from the Common Crawl archive (then `scrapedAt`\nis the archive capture date), `live` for pages Kenso scraped, and `imported`\nfor content supplied in a CSV upload (then `scrapedAt` is the upload time). Ordered home,\nabout, pricing, products, customer pages, careers, then the rest; newest first within\na type. Pages without content are left out. At most 50 pages, not paginated.\nRequires `ReadAccess`.",
        "operationId": "contacts.list-website-pages",
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactWebsitePageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactWebsitePageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfContactWebsitePageModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits": {
      "get": {
        "tags": [
          "credits"
        ],
        "summary": "Return the workspace's credit balance.",
        "description": "Balance, included and purchased credits, debt, the monthly infra reservation and what is available for\ndata and AI work, plus included sends, free builds and the auto top-up rule. A white-label child sees\nits master's pooled balance. Read only. Any member of the workspace (DEV-1654); without the `billing`\nfeature the response omits the billing details (`includedMillicredits`, `purchasedMillicredits`,\n`debtMillicredits`, `reservedMonthlyMillicredits`, `includedExpiresAt`,\n`grandfatheredUntil`, `autoTopUp`, `reservedItems`, `pendingCreditPurchases`,\n`unpaidRenewals`) and keeps the balance, what is available, `exempt`, `exhaustedAt`,\n`creditState`, the monthly included credits, sends and builds.",
        "operationId": "credits.get",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditBalanceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditBalanceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditBalanceModel"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits/ledger": {
      "get": {
        "tags": [
          "credits"
        ],
        "summary": "List the workspace's credit ledger.",
        "description": "Newest first, cursor paginated. A master or standalone workspace sees every line its account was debited\nfor, its white-label children's included (`workspaceId` is the child); a child sees only its own\nlines. Optional filters: `from`, `to` (inclusive instants), `action`, `campaignId` and\n`category` (comma-separated, any matches: `infrastructure`, `ai`, `data`, `sending`,\n`calling`, `added_expired`; a refund or write-off goes with its charge). Each line carries its `category`.\nNeeds the `billing` feature.",
        "operationId": "credit-ledger.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "description": "Page size, 1-200 (default 50).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "From",
            "in": "query",
            "description": "Lines created at or after this instant (UTC).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "description": "Lines created at or before this instant (UTC).",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Action",
            "in": "query",
            "description": "One credit action, e.g. `email_found`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Category",
            "in": "query",
            "description": "Comma-separated spend categories, any of them matches: `infrastructure`, `ai`,\n            `data`, `sending`, `added_expired`. A refund or write-off goes with its charge's category.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCreditLedgerEntryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCreditLedgerEntryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCreditLedgerEntryModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits/spend": {
      "get": {
        "tags": [
          "credits"
        ],
        "summary": "Return what the workspace spent per category in a period.",
        "description": "Net millicredits per spend category (`infrastructure`, `ai`, `data`, `sending`,\n`calling`, always all five), each with its USD amount in cents at $0.02 a credit, plus the total and the number of grant, expiry and\nadjustment lines (`addedExpiredLineCount`). A refund or overrun write-off counts against its charge's\ncategory; not-charged (shadow) lines count as lines but add no spend. `period` is `billing_month`\n(default: the current billing month, or since signup on the Free plan, reported as `since_signup`),\n`last_30_days` or `all_time`. Scoped like the ledger: a master or standalone workspace includes its\nwhite-label children, a child sees its own lines. Read only. Needs the `billing` feature.",
        "operationId": "credit-spend.get",
        "parameters": [
          {
            "name": "period",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditSpendModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditSpendModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditSpendModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits/rate-card": {
      "get": {
        "tags": [
          "credits"
        ],
        "summary": "Return the credit rate card.",
        "description": "The price of every credit action. Static: it does not depend on the workspace and sends no\n`X-Ken-Workspace-Id`. `millicreditsPerUnit` is per one unit; `unitSize` is the quantity prices\nare usually quoted for. Domain rows apply per whole dollar of `ceil(registrarUsd x 1.03) + 1`. The\n`web_scrape` row (per 1,000 pages, at 2x Firecrawl cost) is listed only once Kenso's Firecrawl price is\nconfigured, and the `podcast_search` row (per 1,000 Firecrawl credits a podcast lookup uses, at 2x Firecrawl\ncost) with it. The two places rows (a search page of up to 200 places, and a detail, reviews or photos open past\n500 free a day) are listed only while Maps Data can run (MapsData:Enabled with an API key set). Any signed-in person.",
        "operationId": "credit-rate-card.get",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditRateCardModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditRateCardModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditRateCardModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits/estimates": {
      "post": {
        "tags": [
          "credits"
        ],
        "summary": "Estimate the credits a campaign, a build, an infra purchase, adding accounts, importing leads or places searches need.",
        "description": "Computes only; nothing is charged or reserved. `kind` is `campaign` (target leads, steps,\npersonalization; defaults come from `campaignId`), `build` (a typical campaign build, or 0 when the\nfree monthly build is left), `infra` (`items`; monthly items count their first month upfront) or\n`accounts` (`accountCount`, 1-1,000: an estimated 12 credits of account research per account, metered\nper run, plus about 6 valid committee emails, charged only when found) or `leads` (`leadCount`,\n1-1,000,000: 1.45 credits a lead, from about 3 rows qualified, 1 valid email found and 1 personalization)\nor `places` (`pages`, 0-1,000, at 1 credit a search page of up to 200 places, and `opens`,\n0-100,000, free for the first 500 a workspace a day and then 0.05 credits an open; send at least one above 0).\nFields that do not belong to the kind are rejected. Campaign, build, accounts, leads and places estimates are\nmeasured against available credits, infra against the whole balance, and its inbox and domain lines against\n`inboxDomainEligibleMillicredits` (infra only: free and bonus credits cannot pay them). Any member of the\nworkspace.",
        "operationId": "credit-estimates.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCreditEstimateRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCreditEstimateRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCreditEstimateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditEstimateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditEstimateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditEstimateModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits/savings": {
      "get": {
        "tags": [
          "credits"
        ],
        "summary": "Return what Kenso did free for the workspace, at Clay's prices.",
        "description": "The window is UTC days, both inclusive: `to` defaults to today and `from` to the first of `to`'s\nmonth, at most 366 days. Items: `ken_db_email`, `email_verification`, `enrichment_person`,\n`enrichment_company`, `enrichment_tech_stack` and `website_page` (always all six, in this order),\nthen `launch_offer` when the launch offer covered work. Kenso Search people are recorded but left out while\nClay's people search is free. Each item is its units and their value in cents at Clay's unit price\n(`unitPriceUsdMicros`, millionths of a dollar); `totalUsdCents` is the sum of the items, and each item\nthe sum of its rows in `credit-savings-rows.list`. `lifetime` is every day since the first one recorded.\nAn exempt workspace's savings are only its free work, never its not-charged shadow lines. Any member of the\nworkspace except a Client seat; a Client seat and a white-label client workspace get `404 not_found`. Read only.",
        "operationId": "credit-savings.get",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditSavingsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditSavingsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCreditSavingsModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits/savings/rows": {
      "get": {
        "tags": [
          "credits"
        ],
        "summary": "List the daily rows behind the workspace's Free with Kenso savings.",
        "description": "One row per UTC day, item and campaign (`campaignId` absent outside a campaign), newest day first, then item\nand campaign; cursor paginated. Same window and items as `credit-savings.get`, whose items each sum these\nrows. Optional `item` keeps one item's rows; `ken_search_person` has none while Clay prices it at $0.\nAny member of the workspace except a Client seat; a Client seat and a white-label client workspace get\n`404 not_found`. Read only.",
        "operationId": "credit-savings-rows.list",
        "parameters": [
          {
            "name": "From",
            "in": "query",
            "description": "First UTC day, inclusive. Defaults to the first of `to`'s month.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "To",
            "in": "query",
            "description": "Last UTC day, inclusive. Defaults to today.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "Item",
            "in": "query",
            "description": "One item, e.g. `ken_db_email`; every item when absent.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Page size, 1-200 (default 50).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCreditSavingsRowModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCreditSavingsRowModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCreditSavingsRowModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/crm-connections": {
      "get": {
        "tags": [
          "crm-connections"
        ],
        "summary": "List the workspace's CRM connection.",
        "description": "At most one live connection (connected, needs_reconnect or paused). Empty when none.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-connections.list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmConnectionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmConnectionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmConnectionModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      },
      "post": {
        "tags": [
          "crm-connections"
        ],
        "summary": "Connect a CRM.",
        "description": "OAuth providers (hubspot, salesforce, ...) answer 200 with `authorizeUrl`: send the browser there, and\nfinish with `POST /v1/crm-connections/oauth/complete`. ApiKey providers take `apiKey` (and\n`baseUrl` when self-hosted) and answer 201 with the connection. The CRM the workspace is already connected\nto can be authorized again (a lost token, a missing scope): the same CRM account keeps its connection. 402\n`plan_required` on the Free plan, 409 `crm_already_connected` when another CRM is connected, 404 when\nthe provider is not available to the workspace. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-connections.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectCrmBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectCrmBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectCrmBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmAuthorizeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmAuthorizeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmAuthorizeModel"
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/oauth/complete": {
      "post": {
        "tags": [
          "crm-connections"
        ],
        "summary": "Finish an OAuth connect.",
        "description": "The CRM sends the browser to the web app's `/crm/oauth/callback` page, which posts the `code`,\n`state` and any provider `error` here as the signed-in user. Send `X-Ken-Workspace-Id` as the\npart of `state` before the first dot. Only the person who started the connect, in that workspace, within\n10 minutes, can finish it: anything else is 400 `invalid_state` and changes nothing. Returns the\nconnection, its provider and the `returnPath` sent with the connect. Errors: 400 `provider_error`\n(consent denied), 400 `exchange_failed`, 402 `plan_required`, 409 `crm_already_connected`,\n409 `crm_account_mismatch`, 503 `provider_unavailable`. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-connections.complete-oauth",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteCrmOAuthBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteCrmOAuthBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CompleteCrmOAuthBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmOAuthCompletionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmOAuthCompletionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmOAuthCompletionModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}": {
      "get": {
        "tags": [
          "crm-connections"
        ],
        "summary": "Get a CRM connection.",
        "description": "Any status, disconnected included. Another workspace's id is not_found.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-connections.get",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      },
      "patch": {
        "tags": [
          "crm-connections"
        ],
        "summary": "Update sync settings and switch sync objects on or off.",
        "description": "Omitted fields keep their value. Turning an object on needs the first import completed (409 `import_pending`)\nand CRM writes enabled (409 `crm_sync_disabled`). `pipelineExternalId` must exist in the CRM;\n`stageMap` values must be live Ken opportunity stage keys. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-connections.update",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCrmConnectionBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCrmConnectionBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCrmConnectionBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmConnectionModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      },
      "delete": {
        "tags": [
          "crm-connections"
        ],
        "summary": "Disconnect the CRM.",
        "description": "Stops every sync and deletes Ken's token. Ken's records, the CRM links and the CRM's own data stay. 204, also when\nalready disconnected. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-connections.delete",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/preview": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Preview what turning sync on would do.",
        "description": "Records matched by the import, CRM records Ken would create now under the create rule, and CRM field values Ken\nwould change, with samples. Nothing is written. 409 `import_pending` until the first import finished.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-connections.preview",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmPreviewModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmPreviewModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmPreviewModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/imports": {
      "post": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Import now.",
        "description": "Reads every record from the CRM again; writes nothing to it. 409 `import_running` while one runs. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-imports.create",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmImportModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmImportModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmImportModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/sync": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Sync health.",
        "description": "Per object switch state and last inbound change, the outbound queue, Needs attention count and inbound backlog.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-sync.get",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmSyncHealthModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmSyncHealthModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmSyncHealthModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/sync-issues": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "List sync issues (Needs attention).",
        "description": "Writes the CRM refused, newest first. `limit` 1-200 (default 50), `cursor` from `pagination.nextCursor`.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-sync-issues.list",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmSyncIssueModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmSyncIssueModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmSyncIssueModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/sync-issues/{issueId}/retry": {
      "post": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Retry a sync issue.",
        "description": "Sends the write to the CRM again on the next drain. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-sync-issues.retry",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/sync-issues/{issueId}": {
      "delete": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Dismiss a sync issue.",
        "description": "Ken stops retrying the write. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-sync-issues.dismiss",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "issueId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/field-mappings": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Get the field mapping.",
        "description": "`objectType` company, contact or deal (omit for all three). Also returns the Ken fields a mapping can name.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-field-mappings.list",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "objectType",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmFieldMapModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmFieldMapModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmFieldMapModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      },
      "put": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Replace one object's field mapping.",
        "description": "Every mapping of `objectType` is replaced. Checked against the CRM's fields and Ken's field catalog; Ken's own\nfields always sync from Ken. Requires the integrations permission.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-field-mappings.replace",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCrmFieldMappingsBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCrmFieldMappingsBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceCrmFieldMappingsBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmFieldMapModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmFieldMapModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCrmFieldMapModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/fields": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "List the CRM's fields.",
        "description": "`objectType` company, contact or deal. Cached 10 minutes. Ken's own fields that Ken creates on sync are listed with `exists: false`.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-fields.list",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "objectType",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmFieldModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmFieldModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmFieldModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/pipelines": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "List the CRM's deal pipelines and stages.",
        "description": "Needs the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-pipelines.list",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmPipelineModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmPipelineModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmPipelineModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/records": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "Look up a CRM record.",
        "description": "By `email`, `domain`, or `externalId` with `objectType`. What Ken holds for the record and the Ken record it is linked to. No CRM call.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-records.lookup",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Email",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Domain",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ExternalId",
            "in": "query",
            "description": "The CRM's own record id.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ObjectType",
            "in": "query",
            "description": "company, contact, deal, owner, activity or list. Required with externalId.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmRecordModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmRecordModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmRecordModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/crm-connections/{connectionId}/lists": {
      "get": {
        "tags": [
          "crm-sync"
        ],
        "summary": "List the CRM's lists.",
        "description": "For list sources (settings.listSources). Empty for a CRM without lists.\n\nNeeds the `ingestion` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "crm-lists.list",
        "parameters": [
          {
            "name": "connectionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCrmListModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "ingestion"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/custom-variables": {
      "get": {
        "tags": [
          "custom-variables"
        ],
        "summary": "List a campaign's custom variables.",
        "description": "Ordered by key. `q` matches the key or the name. Requires `ReadAccess`.",
        "operationId": "custom-variables.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCustomVariableModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCustomVariableModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCustomVariableModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "custom-variables"
        ],
        "summary": "Declare one custom variable.",
        "description": "Returns `201` and `Location`. An existing key is updated. Requires `WriteAccess`.",
        "operationId": "custom-variables.create",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomVariableRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomVariableRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateCustomVariableRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCustomVariableModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCustomVariableModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCustomVariableModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/custom-variables/{variableKey}": {
      "patch": {
        "tags": [
          "custom-variables"
        ],
        "summary": "Update one custom variable.",
        "description": "Absent fields stay unchanged. Requires `WriteAccess`.",
        "operationId": "custom-variables.update",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCustomVariableRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCustomVariableRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateCustomVariableRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCustomVariableModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCustomVariableModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCustomVariableModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "custom-variables"
        ],
        "summary": "Remove one custom variable.",
        "description": "Requires `WriteAccess`. Returns `204`.",
        "operationId": "custom-variables.delete",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/domain-health-checks": {
      "post": {
        "tags": [
          "domain-health-checks"
        ],
        "summary": "Start a domain health check.",
        "description": "Returns `202` with a `domain_health` job. A check already running for the\nworkspace is `409 conflict` and `data.id` is that running job. Requires `WriteAccess`.\nExample: `{ \"domainIds\": [4, 9] }`.",
        "operationId": "domain-health-checks.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDomainHealthCheckRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDomainHealthCheckRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDomainHealthCheckRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains": {
      "get": {
        "tags": [
          "domains"
        ],
        "summary": "List domains in the current workspace.",
        "operationId": "domains.list",
        "parameters": [
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfDomainModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfDomainModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfDomainModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/bulk-update": {
      "post": {
        "tags": [
          "domains"
        ],
        "summary": "Apply one field update to up to 1,000 domains.",
        "description": "Requires `WriteAccess`. Auto-renew requires Delivery edit and the Billing feature. Masking and catch-all require `SuperAdmin`.\n            `websiteMode` (`redirect` or `page`) records the person's answer to \"rebuild or redirect\"; it cannot be cleared.",
        "operationId": "domains.bulk-update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/{domainId}": {
      "get": {
        "tags": [
          "domains"
        ],
        "summary": "Return one domain in the current workspace.",
        "operationId": "domains.get",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "domains"
        ],
        "summary": "Update a domain. Absent fields stay unchanged. Null clears text fields and tag ids.",
        "description": "Requires `WriteAccess`. Auto-renew requires Delivery edit and the Billing feature. Masking and catch-all require `SuperAdmin`.\n            `websiteMode` (`redirect` or `page`) records the person's answer to \"rebuild or redirect\"; it cannot be cleared.",
        "operationId": "domains.update",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "domains"
        ],
        "summary": "Delete a domain.",
        "description": "Returns `204`. Requires `WriteAccess`.",
        "operationId": "domains.delete",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/domains/{domainId}/health": {
      "get": {
        "tags": [
          "domains"
        ],
        "summary": "Return the latest health snapshot for one domain.",
        "description": "Blacklist, mail DNS, bounce, placement, nameserver, and certificate state.\n`spfStatus`, `dkimStatus`, `dmarcStatus` and `mxStatus` are `pass`, `fail` or\n`unknown`, omitted before the first check. They and the blacklist come from the last health snapshot\n(the daily health sweep, or `POST /v1/domain-health-checks`, a 202 job) dated by `checkedAt`, and do\nnot change until the next check runs. Rates are fractions from 0 to 1. A domain outside the workspace is\n`not_found`.",
        "operationId": "domains.get-health",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainHealthModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainHealthModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainHealthModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/{domainId}/dns": {
      "get": {
        "tags": [
          "domains"
        ],
        "summary": "Return tracking DNS state for one domain.",
        "operationId": "domains.get-dns",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainDnsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainDnsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainDnsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/{domainId}/verify-dns": {
      "post": {
        "tags": [
          "domains"
        ],
        "summary": "Verify Kenso tracking DNS for one domain.",
        "description": "Requires `WriteAccess`.",
        "operationId": "domains.verify-dns",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainDnsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainDnsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainDnsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/{domainId}/check-nameservers": {
      "post": {
        "tags": [
          "domains"
        ],
        "summary": "Check imported-domain nameservers against the Kenso Cloudflare zone.",
        "description": "Requires Delivery edit access (owners, admins and editors by default).",
        "operationId": "domains.check-nameservers",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainNameserverCheckModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainNameserverCheckModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainNameserverCheckModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/domains/{domainId}/website": {
      "get": {
        "tags": [
          "domains"
        ],
        "summary": "Return what people see on one domain: its website mode and each hostname's page status.",
        "description": "`mode` is `unset` (nobody answered: the domain keeps its redirect), `redirect` or `page`.\n            `currentVersionId` is the workspace's live page version, null until the first publish. `hostnames` lists\n            the apex first, then `www`, each with `attachPath` (`worker_route`, `custom_hostname` or null when\n            unsupported), `dnsWriter`, `status` (`detached`, `attaching`, `active`, `detaching` or\n            `failed`), `sslStatus`, `unsupportedReason` and `checkedAt`; empty until Kenso has checked the\n            domain. Requires `ReadAccess` and the `domain_pages` feature.\n\nNeeds the `domain_pages` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "outbound-site.domain-get",
        "parameters": [
          {
            "name": "domainId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainWebsiteModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainWebsiteModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfDomainWebsiteModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "domain_pages"
        ]
      }
    },
    "/v1/email-copy-grades": {
      "post": {
        "tags": [
          "email-copy-grades"
        ],
        "summary": "Grade sequencer email or LinkedIn copy for clarity.",
        "description": "`channel` is `email` (default), `linkedin_connection` or `linkedin_message`;\n            any other value is 400 on `channel`. Email sends the text to Jev using the client-system\n            copy questions and returns those scores plus an overall band (keep, rewrite, start_over).\n            Callers prefix a follow-up themselves. A LinkedIn step returns five 0-10 bars (quick_read,\n            cta, easy, weird_word, personal), their mean as the score, keep at 7.5 or more with no\n            weird_word alarm, rewrite at 5.5 or more, else start_over; a connection note over 300\n            characters fails easy. A saved grade for `subjectKey` and channel is returned even when\n            the copy changed. `refresh: true` grades the new copy and replaces that row, and needs\n            campaigns edit (403 otherwise). Requires campaigns view and Ask. Each call takes one unit of the\n            workspace's `aiEmailCopyGrades` quota (20 a minute, 500 a day, every caller kind): past it,\n            429 `quota_exceeded` with `Retry-After`.\n            `campaignId` is optional: a recruiting campaign of the workspace grades with the recruiting rubric and\n            saves under its own key, so its `subjectKey` is at most 149 characters (129 on linkedin_connection, 132 on\n            linkedin_message); another workspace's campaign is 404. A `subjectKey` cannot start with `recruiting:`.",
        "operationId": "email-copy-grades.grade",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GradeEmailCopyRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/GradeEmailCopyRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/GradeEmailCopyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailCopyGradeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailCopyGradeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailCopyGradeModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable"
          },
          "504": {
            "description": "Gateway Timeout"
          }
        }
      }
    },
    "/v1/email-copy-lints": {
      "post": {
        "tags": [
          "email-copy-lints"
        ],
        "summary": "Lint sequencer email copy against the email-review rules.",
        "description": "Send the step's `subject`, its `body` (plain text or the editor's HTML), its `stepOrder` (1, the\ndefault, is the first email; 2 and up are follow-ups), `variables` (the AI variable names that have a\npersonalization prompt), `customVariableKeys` (the campaign's registered custom variable keys) and\n`isFinanceVertical` (true for a finance, insurance, real-estate or lending client, whose domain words then do\nnot count toward the MEDIUM budget). Returns every rule in a fixed order, each\n`pass`, `fail` (severity `reject` or `flag`) or `skipped`, with the text it matched;\n`passed` is false when any rule failed at `reject`. The same input always returns the same result. No model\nruns, so it does not judge whether a claim is true, an offer is clear or a CTA asks for the real offer: that is\nthe review's reading (and the `email-copy-grades` grade). Rules: subject 1-60 characters; body 40-180 words;\nstatic words 50-80 on email 1 and 30-60 on a follow-up (over is reject, under is flag); no em dash; at most one\nlink, https, no shortener, no web address as link text; no [square bracket], TODO or TBD placeholder; every\n{lead variable} accepted by the sequence save (custom keys only when listed in `customVariableKeys`), no {a|b}\nspintax and no {sender_signature}; lead variables that\noften render blank (flag); every {{AI variable}} named in `variables` (skipped when `variables` is\nomitted); on email 1 a static opener that names a number, name or place (flag), has no first person, praise or\nhedging, and runs 8-20 words (flag), and a next sentence that does not jump to a generic statement (flag);\nspam tiers: a NEVER word or fake Re:/Fwd: rejects, one HIGH word flags and two reject, three MEDIUM words\nreject, any tiered word, $, % or two numbers in the subject rejects, and an ALL CAPS word, more than one !, or\n!!! / ??? rejects. Requires campaigns view. A blank body, a body over 20,000 characters, a subject over 1,000,\na `stepOrder` outside 1-30, or more than 100 `variables` or `customVariableKeys` is 400.",
        "operationId": "email-copy-lints.lint",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/LintEmailCopyRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/LintEmailCopyRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/LintEmailCopyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailCopyLintModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailCopyLintModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailCopyLintModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/email-finds": {
      "post": {
        "tags": [
          "email-finds"
        ],
        "summary": "Find one person's email by name and company.",
        "description": "Body: a name (`fullName`, or `firstName` and `lastName`) and `companyDomain` (the company's\nwebsite domain, such as `acme.fr`; free mail, social and link hosts are `400 invalid_domain`) or\n`linkedinUrl`, or both; `companyName` is optional. With only `linkedinUrl`, the domain is the\nperson's current company in Kenso Search, and the find ends `not_found` (free) when Kenso Search does not know\nit. Works for any country. Kenso asks its own email\ndatabase, then Prospeo, LeadMagic and Findymail, verifies each answer and keeps the first valid (safe or\nverified) email. 1 credit when a Kenso-paid lookup finds one, nothing for a miss or a find on the workspace's own\nprovider key. Out of credits it is `402 plan_limit_reached` with `error.refusal` and nothing runs.\nThe person is kept in the workspace (on no account): the person an earlier lookup made for this name at this domain\n(unless they hold another LinkedIn URL), else the person a `linkedinUrl` names, else a new one. So a repeat\nlookup that adds `linkedinUrl` makes no second person. A person is reused only when they have no email,\ntheir email is the one an earlier lookup at this domain found, or it is at `companyDomain`; one who already\nhas it gets it back found, at no charge, with verification `unverified`. Parallel calls for the same name and\ndomain are not merged: send one and poll it. Returns `202` with the find (status `queued`); it usually\nends within a minute: poll `GET /v1/email-finds/{emailFindId}`. A person whose lookup is still working gets\nthat find back (`409 active_find` when it is for another company). 30 lookups a minute and 500 a day per\nworkspace (a 400, 402, 403 or 409, or a call that gets a running find back, does not count); past it,\n`429 quota_exceeded` with `Retry-After`. With account scope `own` it is `403`. Requires the\nSearch page (edit). Behind the `email_finder` feature (404 when off).\n\nNeeds the `email_finder` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "email-finds.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEmailFindBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEmailFindBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateEmailFindBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailFindModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailFindModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailFindModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "email_finder"
        ]
      }
    },
    "/v1/email-finds/{emailFindId}": {
      "get": {
        "tags": [
          "email-finds"
        ],
        "summary": "Read one email find.",
        "description": "The find `POST /v1/email-finds` queued. `status` is `queued`, `running` or `paused`\nwhile it works (`pausedReason``credits` or `member_limit`), then `found`, `not_found`\nor `failed` (`error` says why; a failed find may be asked again). Found, it carries `email`,\n`provider` and `verification` (`status` safe, verified or unverified, and `verifiedBy`), and\n`costCredits` is what it charged. Another workspace's find is `404`. With account scope `own` it is\n`403`, as on create. Requires the Search page (view). Behind the `email_finder` feature (404 when off).\n\nNeeds the `email_finder` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "email-finds.get",
        "parameters": [
          {
            "name": "emailFindId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailFindModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailFindModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailFindModel"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "email_finder"
        ]
      }
    },
    "/v1/event-occurrences": {
      "get": {
        "tags": [
          "event-occurrences"
        ],
        "summary": "Poll MCP events after a cursor.",
        "description": "Read only, any workspace member. Without `cursor` it returns no events and a cursor at now, and the\nworkspace starts logging its MCP events (each poll keeps that going for 7 days). Pass back `cursor`\nunchanged. `types` is a comma-separated list of MCP event types (omitted: every one you may receive;\n`GET /v1/webhook-event-types` marks them `mcp`). `campaignId` and `classification` narrow\nevents that carry them. `limit` is 1 to 100 (default 50). `maxAgeMs` skips older events instead of\nreplaying them, with `truncated: true`. `hasMore: true` means poll again at once; otherwise wait\n`nextPollMs`. Events are kept 7 days. 404 when MCP events are not enabled for the workspace;\n`unsupported` for a type that is not an MCP event; 403 for a type whose page you cannot see.",
        "operationId": "event-occurrences.poll",
        "parameters": [
          {
            "name": "Cursor",
            "in": "query",
            "description": "The `cursor` of the previous poll. Omitted: start from now (no events, a fresh cursor).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Types",
            "in": "query",
            "description": "Comma-separated MCP event type names. Omitted: every MCP type you may receive.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "description": "Only events of this campaign.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Classification",
            "in": "query",
            "description": "Only events with this reply classification, such as `interested`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "1 to 100, default 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "MaxAgeMs",
            "in": "query",
            "description": "Skip events older than this many milliseconds instead of replaying them. Ignored without a cursor.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventOccurrencesModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventOccurrencesModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventOccurrencesModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/event-subscriptions": {
      "get": {
        "tags": [
          "event-subscriptions"
        ],
        "summary": "List your MCP event webhook subscriptions in the current workspace.",
        "description": "Only your own, newest first; expired and terminated ones stay listed for 7 days. The signing secret is never returned.",
        "operationId": "event-subscriptions.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfEventSubscriptionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfEventSubscriptionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfEventSubscriptionModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "event-subscriptions"
        ],
        "summary": "Create or renew an MCP event webhook subscription.",
        "description": "Requires the integrations feature and the event group's page; a machine key without a member is 403. Keyed by\n(you, `delivery.url`, `name`, `arguments`): the same key renews (200), a new one creates (201).\n`delivery.mode` is `webhook`; `delivery.url` is https and must resolve to a public address;\n`delivery.secret` is `whsec_` + base64 of 24 to 64 random bytes, stored encrypted and never returned\n(a renewal may rotate it). The first subscription to a URL POSTs a signed\n`{\"type\":\"verification\",\"challenge\":...}` and needs `{\"challenge\":...}` echoed in a 2xx body, else\n`callback_verification_failed` with the category in `error.details[0].code`. The grant\n(`refreshBefore`) is at most one hour: subscribe again before it. `cursor` starts a new or lapsed\nsubscription there (null: now; `maxAgeMs` bounds the replay); a live one keeps its own. At most 50 active\nsubscriptions per workspace (`resource_exhausted`). 404 when MCP events are not enabled for the workspace.",
        "operationId": "event-subscriptions.upsert",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertEventSubscriptionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertEventSubscriptionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertEventSubscriptionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionGrantModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionGrantModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionGrantModel"
                }
              }
            }
          },
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionGrantModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionGrantModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionGrantModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/event-subscriptions/{eventSubscriptionId}": {
      "get": {
        "tags": [
          "event-subscriptions"
        ],
        "summary": "Get one of your MCP event webhook subscriptions.",
        "operationId": "event-subscriptions.get",
        "parameters": [
          {
            "name": "eventSubscriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventSubscriptionModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "event-subscriptions"
        ],
        "summary": "Delete one of your MCP event webhook subscriptions.",
        "description": "Requires the integrations feature. Deliveries stop at once and the signing secret is deleted. Another member's subscription is not found.",
        "operationId": "event-subscriptions.delete",
        "parameters": [
          {
            "name": "eventSubscriptionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/event-subscriptions/unsubscribe": {
      "post": {
        "tags": [
          "event-subscriptions"
        ],
        "summary": "Unsubscribe by event, arguments and URL.",
        "description": "SEP-3415 `events/unsubscribe`: `name`, `arguments` and `delivery.url` must match one of your\nsubscriptions exactly, else 404. Requires the integrations feature. Deliveries stop at once and the signing secret is deleted.",
        "operationId": "event-subscriptions.unsubscribe",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UnsubscribeEventSubscriptionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UnsubscribeEventSubscriptionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UnsubscribeEventSubscriptionRequest"
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/events": {
      "get": {
        "tags": [
          "events"
        ],
        "summary": "List workspace webhook events.",
        "operationId": "events.list",
        "parameters": [
          {
            "name": "Type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfEventModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfEventModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfEventModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/events/counts": {
      "get": {
        "tags": [
          "events"
        ],
        "summary": "Return event counts for one campaign and the public event type catalog.",
        "operationId": "events.get-counts",
        "parameters": [
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "From",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventCountsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventCountsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEventCountsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/external-bookings": {
      "get": {
        "tags": [
          "external-bookings"
        ],
        "summary": "List third-party bookings.",
        "description": "Ordered by start, then id. Filters: `provider` (cal_com, calendly, hubspot or chili_piper, comma = OR);\n`status` (booked, rescheduled, cancelled or no_show, comma = OR); `campaignId` (the credited campaign),\n`accountId` and `personId`; `startAfter` (start at or after) and `startBefore` (start before).\nEach filter narrows the bookings the caller sees. `limit` 1-200 (default 50), `cursor` from\n`pagination.nextCursor`. An unknown provider or status is 400 validation_failed. Needs the meetings feature and\nthe Calendar page (view).\n\nNeeds the `meetings` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "external-bookings.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Provider",
            "in": "query",
            "description": "cal_com, calendly, hubspot or chili_piper; comma = OR.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "description": "booked, rescheduled, cancelled or no_show; comma = OR.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "description": "Only bookings credited to this campaign.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "AccountId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "PersonId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "StartAfter",
            "in": "query",
            "description": "Start at or after.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "StartBefore",
            "in": "query",
            "description": "Start before.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfExternalBookingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfExternalBookingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfExternalBookingModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "meetings"
        ]
      }
    },
    "/v1/external-bookings/{externalBookingId}": {
      "get": {
        "tags": [
          "external-bookings"
        ],
        "summary": "Get a third-party booking.",
        "description": "404 for a booking in another workspace or one the caller cannot see (as on the list). Needs the meetings feature and\nthe Calendar page (view).\n\nNeeds the `meetings` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "external-bookings.get",
        "parameters": [
          {
            "name": "externalBookingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfExternalBookingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfExternalBookingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfExternalBookingModel"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "meetings"
        ]
      }
    },
    "/v1/funding-rounds/search": {
      "post": {
        "tags": [
          "funding-rounds"
        ],
        "summary": "Search funding rounds.",
        "description": "Filters: `companies`, `industries`, `location`, `amountRaisedUsd`,\n`roundRaisedUsd`, `roundSizeUsd` (whole USD min and max), `reportedWithinDays`,\n`reportedAfter`, `reportedBefore`, `newRoundsOnly`, `revenueRanges`,\n`companyKinds`, `hasDomain`, `foundedWithinYears` and `companyIds`. All are\noptional and unknown keys return 400 `validation_failed`. `limit` and cursor pagination\nthrough `pagination.nextCursor`. `groupBy: \"company\"` returns one row per company and\n`includeFacets: true` adds facet counts. A rejected request returns 400\n`validation_failed` with the reason code (for example `invalid_cursor`) in\n`details[0].code`. Free: does not use the export allowance.",
        "operationId": "funding-rounds.search",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/funding-rounds/search/export": {
      "post": {
        "tags": [
          "funding-rounds"
        ],
        "summary": "Export funding rounds as JSON or CSV.",
        "description": "Same filters as search, plus `format` (`json` default, or `csv`) and `limit`\n(default 100). The export runs with min(limit, 5000, remaining monthly allowance) rows. A larger\nmatch set returns 422 `export_limit_exceeded` with `details[0].count` and\n`details[0].limit`, and uses nothing. A rejected request returns 400 `validation_failed`\nand also uses nothing. No allowance left returns 402 `plan_limit_reached` with refusal code\n`FUNDING_EXPORT_ROWS_LIMIT_REACHED`. Success uses one allowance row per returned row and sets\n`X-Ken-Row-Count`. CSV is a file download named `funding-rounds-{yyyyMMdd-HHmmss}.csv`.",
        "operationId": "funding-rounds.export",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/funding-rounds/export-allowance": {
      "get": {
        "tags": [
          "funding-rounds"
        ],
        "summary": "Get the funding export allowance for this calendar month.",
        "description": "Free. The allowance resets on the first of each month, UTC.",
        "operationId": "funding-rounds.get-export-allowance",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfFundingRoundsExportAllowanceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfFundingRoundsExportAllowanceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfFundingRoundsExportAllowanceModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/funding-rounds/{fundingRoundId}": {
      "get": {
        "tags": [
          "funding-rounds"
        ],
        "summary": "Get one funding round.",
        "description": "`fundingRoundId` is `fr_` followed by 18 digits; anything else is 404 `not_found`.\n            Returns the round, its company and people, and `history`: the earlier rounds of the same\n            offering, oldest first. Free. Does not use the export allowance.",
        "operationId": "funding-rounds.get",
        "parameters": [
          {
            "name": "fundingRoundId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/funding-rounds/filters/resolve": {
      "post": {
        "tags": [
          "funding-rounds"
        ],
        "summary": "Resolve partial company, industry, state or person text for filter autocomplete.",
        "description": "Body: `field` (`companies`, `industries`, `states` or `people`),\n`query` and `limit`. Returns `values` with `value`, `label` and\n`count`. Free. Does not use the export allowance.",
        "operationId": "funding-rounds.resolve-filters",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/image-variables": {
      "get": {
        "tags": [
          "image-variables"
        ],
        "summary": "List a campaign's image variables.",
        "description": "Ordered by key, at most 5, one page (`hasMore` is always false). Beside `data`: `linkHostReady` (the\nworkspace has a link host to serve images from; without one no image variable can be created or sent),\n`coverage` (`leads` plus, per reference wire name, how many leads have that reference) and `models`\n(each image model with its estimated credits per per_prospect image). Requires the Campaigns page.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ImageVariableListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageVariableListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImageVariableListResponse"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      },
      "post": {
        "tags": [
          "image-variables"
        ],
        "summary": "Create an image variable.",
        "description": "Returns `201` and `Location`. `key` shares the namespace of custom and AI variables and is\nnormalized (`Hero Image` becomes `hero_image`); `custom_image` and a key a custom, AI or image\nvariable of the campaign has are 409 `variable_key_taken`. No link host in the workspace is 409\n`link_host_required`; a sixth variable is 409 `image_variable_limit`. A new variable starts off:\n`enabled: true` is a 400 on `enabled`, and `false` or absent is accepted. Turn it on with PATCH after\nreading its estimate. Requires Campaigns edit.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.create",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateImageVariableRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateImageVariableRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateImageVariableRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/image-variables/{variableKey}": {
      "get": {
        "tags": [
          "image-variables"
        ],
        "summary": "Get one image variable.",
        "description": "A shared variable carries its current image with a presigned `previewUrl` (1 hour). Requires the Campaigns page.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.get",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      },
      "patch": {
        "tags": [
          "image-variables"
        ],
        "summary": "Update an image variable.",
        "description": "Absent fields stay unchanged; `prompt` and `altText` are cleared by null or blank. `key` and\n`kind` never change (400 on that field). A changed prompt, reference set, model, size or quality replaces\nthe images of leads with no sent or queued step that uses the variable; read the estimate first.\n`enabled: false` is always allowed and keeps the existing images. Requires Campaigns edit.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.update",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateImageVariableRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateImageVariableRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateImageVariableRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      },
      "delete": {
        "tags": [
          "image-variables"
        ],
        "summary": "Delete an image variable.",
        "description": "Returns `204`. 409 `image_variable_in_use` while any step of the campaign holds `{{key}}` in its\nbody or subject: remove it there first, or disable the variable instead. Its images stay. Requires Campaigns edit.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.delete",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/image-variables/{variableKey}/estimate": {
      "post": {
        "tags": [
          "image-variables"
        ],
        "summary": "Estimate what running an image variable would generate and cost.",
        "description": "A read: nothing is written. The body holds optional draft fields (absent = the saved value). `leadsNow` is\nhow many leads would get an image now, already counting the `replaceCount` leads whose current image the\nchange would replace; `creditsNow` = `leadsNow` x `creditsPerImage`. A shared variable is one image\nand 0 per new lead. Every credit field is credits. Requires Campaigns edit.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.estimate",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateImageVariableRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateImageVariableRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/EstimateImageVariableRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableEstimateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableEstimateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableEstimateModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/image-variables/{variableKey}/test": {
      "post": {
        "tags": [
          "image-variables"
        ],
        "summary": "Test a per_prospect image variable on up to 5 leads.",
        "description": "Sync: generates for up to 5 eligible leads (leads with no image first, then leads whose image failed), charged\nper ready image, and returns the images (a lead whose generation failed outright is left out). They become those\nleads' images. A lead whose image Kenso staff blocked is never picked. Does not turn the variable on. A shared\nvariable is 409 `wrong_kind`. Reserves one editor generation per lead it picks (at most 5, none when no\nlead is eligible), after those checks. Requires Campaigns edit.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.test",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableTestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableTestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableTestModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/image-variables/{variableKey}/shared-image": {
      "post": {
        "tags": [
          "image-variables"
        ],
        "summary": "Set a shared image variable's image.",
        "description": "Exactly one source: multipart field `file` (PNG, JPEG or WebP, at most 10 MB), JSON `{ \"url\": \"...\" }`\n(a public https image, fetched once) or JSON `{ \"generate\": true }` (from the prompt, sync and charged;\nreserves 1 editor generation once the checks below pass). Returns the variable; a generation that failed comes\nback as `sharedImage.status``failed` with its `errorCode`, and the image already in use stays. A\nURL that cannot be fetched is 400 on `url`. A per_prospect variable is 409 `wrong_kind`; no link host\nis 409 `link_host_required`. A shared image Kenso staff blocked is not replaced from any source: 409\n`blocked`. Requires Campaigns edit.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.set-shared-image",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfImageVariableModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/image-variables/{variableKey}/contacts/{contactId}/regenerate": {
      "post": {
        "tags": [
          "image-variables"
        ],
        "summary": "Regenerate one lead's image.",
        "description": "Sync and charged per ready image; reserves 1 editor generation once the checks pass. Returns the new image,\nready or failed; the previous image stays in use until a new one is ready. 409 `image_in_use` when the lead\nalready has a sent or queued step that uses the variable, so it keeps that image. 409 `blocked` when Kenso\nstaff blocked the lead's current image: a block covers that one image, not its slot, so a changed prompt still\nlets the generation job make the lead a new one, but this route does not replace it. A lead outside the\ncampaign's image audience is 404; a shared variable is 409 `wrong_kind`. Requires Campaigns edit.\n\nNeeds the `campaign_images` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "image-variables.regenerate-contact",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "variableKey",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignImageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignImageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignImageModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "campaign_images"
        ]
      }
    },
    "/v1/campaigns/{campaignId}/inbound-webhooks": {
      "get": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "List a campaign's inbound webhooks in the current workspace.",
        "description": "Ordered by id. Read-only. Requires `ReadAccess`.",
        "operationId": "inbound-webhooks.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "Create an inbound webhook on a campaign in the current workspace.",
        "description": "Returns `201` and `Location`. Requires the integrations permission (admins by default).",
        "operationId": "inbound-webhooks.create",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboundWebhookRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboundWebhookRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboundWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound-webhooks": {
      "get": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "List the workspace's people webhooks.",
        "description": "A people webhook runs lead intake on every delivery: it creates or updates a person (source `form` for the\nform presets, `visitor` for rb2b and vector, else `webhook`). Ordered by id. A campaign's webhooks are\nlisted under the campaign. Requires the `accounts` and `lead_intake` features. Read-only. Requires\n`ReadAccess`.\n\nNeeds the `accounts` feature on your workspace. Until it is on, calls answer 404. Needs the `lead_intake` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "inbound-webhooks.list-people-sources",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "accounts",
          "lead_intake"
        ]
      },
      "post": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "Create a people webhook in the current workspace.",
        "description": "Returns `201` and `Location`. Each delivery to its URL creates or updates a person. `name` is\nrequired. Give a `preset` (hubspot_forms, typeform, webflow, tally, rb2b, vector, generic, zapier, make,\nn8n) or a `mapping` that maps email, profile_url, or a name with company_domain. zapier, make and n8n are\nthe generic flat keys and set `app`; an `app` alone uses them too. `defaultOwnerMemberId` must\nbe a workspace member. Requires the `accounts` and `lead_intake` features. Requires the integrations permission (admins by default).\n\nNeeds the `accounts` feature on your workspace. Until it is on, calls answer 404. Needs the `lead_intake` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "inbound-webhooks.create-people-source",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboundWebhookRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboundWebhookRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboundWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "accounts",
          "lead_intake"
        ]
      }
    },
    "/v1/inbound-webhooks/{inboundWebhookId}": {
      "get": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "Return one inbound webhook in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Requires `ReadAccess`.",
        "operationId": "inbound-webhooks.get",
        "parameters": [
          {
            "name": "inboundWebhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "Update an inbound webhook.",
        "description": "Absent fields stay unchanged. Requires the integrations permission (admins by default). A `people` webhook also takes `app` (zapier, make\nor n8n, or null to clear it), `defaultOwnerMemberId` (a workspace member, else `invalid_member`; null\nclears it) and `createAccounts` (true or false), keeping its URL, preset and people counters; another kind\nrefuses them with `400` naming the field. `createPerson` is a workflow webhook's, set on its webhook\ntrigger, so here it is refused the same way. A website source (kind `website`) follows the site's visitor-ID\nprovider, set in Settings > Integrations: the next `PATCH /v1/website` that names a provider resumes it and\nresets its mapping to that provider's preset. Set the site's provider to `none` to stop it.",
        "operationId": "inbound-webhooks.update",
        "parameters": [
          {
            "name": "inboundWebhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInboundWebhookRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInboundWebhookRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInboundWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "Soft-delete an inbound webhook.",
        "description": "Requires the integrations permission (admins by default). Returns `204`.",
        "operationId": "inbound-webhooks.delete",
        "parameters": [
          {
            "name": "inboundWebhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/inbound-webhooks/{inboundWebhookId}/rotate-token": {
      "post": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "Rotate the ingest token. The previous URL stops working immediately.",
        "description": "Requires the integrations permission (admins by default).",
        "operationId": "inbound-webhooks.rotate-token",
        "parameters": [
          {
            "name": "inboundWebhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound-webhooks/{inboundWebhookId}/test-mapping": {
      "post": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "Dry-run a mapping against a sample payload.",
        "description": "Does not create a lead. Requires the integrations permission (admins by default).",
        "operationId": "inbound-webhooks.test-mapping",
        "parameters": [
          {
            "name": "inboundWebhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestInboundWebhookMappingRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TestInboundWebhookMappingRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TestInboundWebhookMappingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookMappingTestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookMappingTestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboundWebhookMappingTestModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbound-webhooks/{inboundWebhookId}/deliveries": {
      "get": {
        "tags": [
          "inbound-webhooks"
        ],
        "summary": "List recent deliveries for an inbound webhook.",
        "description": "The delivery log has no numeric id, so this window uses `limit` (1 to 100, default 100)\nand omits `totalCount`. Requires `ReadAccess`.",
        "operationId": "inbound-webhooks.deliveries",
        "parameters": [
          {
            "name": "inboundWebhookId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookDeliveryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookDeliveryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboundWebhookDeliveryModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inbox-imports": {
      "post": {
        "tags": [
          "inbox-imports"
        ],
        "summary": "Connect up to 500 SMTP/IMAP inboxes in the background and return the import job.",
        "description": "Body `rows`: 1 to 500 inboxes with the fields of `POST /v1/inboxes`. Each row runs the same\nconnect (validation, consumer-host guard, white-label mailbox cap, live SMTP AUTH and IMAP LOGIN probe),\nfour at a time. A row with a missing field fails, a row that reuses an earlier row's `username` on the\nsame `smtpHost` or `imapHost` with another password fails, an email an earlier row has is skipped\n(`duplicate_in_file`), and an email the workspace already has is skipped (`already_exists`) unless\nthat inbox is a disconnected SMTP inbox, which the row reconnects. A row logs in before its inbox is created,\nso a failed probe creates no inbox, and `email_in_use` (another inbox in Kenso holds the address) is only\nreported after a successful login. `firstName`, `lastName` and `dailySendLimit` are not\napplied; set them with `PATCH /v1/inboxes/{inboxId}`.\nReturns 202 with the job. Poll `GET /v1/jobs/{jobId}?type=inbox_import` for `inboxImport` counts and\nrows; a job with no progress for 10 minutes fails with `error.code``interrupted`. Passwords are\nnever stored or returned. A workspace can have 2 imports queued or running at once; a third gets 409\n`conflict`. Each row that passes the up-front checks takes one unit of a 1,000 per workspace per rolling\nday limit; an import over it gets 429 `quota_exceeded` with `Retry-After`, and nothing runs.\nRequires delivery edit, the same as `POST /v1/inboxes`, and the `inbox_csv_import` feature flag: while it\nis off for the caller the route answers 404 `not_found`. Both are checked again before each row: once the flag\nis off, or the caller is no longer a member with delivery edit, the import stops, every row it had not started is\n`skipped` with `feature_disabled` or `forbidden`, and the job fails with that `error.code`.\n\nNeeds the `inbox_csv_import` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "inbox-imports.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxImportRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxImportRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxImportRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "inbox_csv_import"
        ]
      }
    },
    "/v1/inboxes/connect-sessions": {
      "post": {
        "tags": [
          "inboxes"
        ],
        "summary": "Start a Gmail or Microsoft connect.",
        "description": "`provider` is `google` or `microsoft`. `purpose` is `primary` (the caller's own\n            mailbox, through the Kenso Workspace app; `not_found` without Kenso Accounts) or `campaign` (a shared\n            campaign mailbox, through Kenso Mail). Open `authorizationUrl` before `expiresAt`; nothing is\n            stored until the connect finishes. It finishes in the Kenso dashboard (DEV-2228): after consent the provider\n            sends the browser there, and the member who created the session (for an API key, its owner) must be signed\n            in, in this workspace. Anyone else is refused and nothing is connected, so a key that names no member cannot\n            finish a connect.\n            Requires delivery edit, like the legacy `authorize` routes. A client seat (Delivery view,\n            `approve_own_sends`) connects only its own primary inbox: `purpose=campaign` is\n            `403 forbidden` with `own_inbox_only`, and a login email off the workspace's email domain (or a\n            workspace with none) is `409 invalid_state` with `email_domain_mismatch`, whose message says what\n            fixes it, because that mailbox would never be its primary inbox. A grant for any mailbox but the caller's login email waits for\n            `POST /v1/inboxes/connect-confirmations`, which needs delivery edit, so a client seat connects only its\n            login email. Declared `[WorkspaceMember]`; the action decides delivery edit or `approve_own_sends` (DEV-1811).\n            Optional `returnTo` (DEV-1611) is a dashboard path the finished connect lands on, on the dashboard's own\n            origin, with the usual result query (`gmail=connected`, `microsoft=error&reason=...`); for\n            Microsoft the admin-consent return lands there too. Anything but a relative path with one leading `/`, no\n            `//`, backslash or control characters, at most 512 characters, is `validation_failed` on\n            `returnTo`. Without it the connect returns to the app's default page.",
        "operationId": "inboxes.create-connect-session",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxConnectSessionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxConnectSessionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxConnectSessionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxConnectSessionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxConnectSessionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxConnectSessionModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inboxes": {
      "get": {
        "tags": [
          "inboxes"
        ],
        "summary": "List inboxes in the current workspace.",
        "description": "`status` is optional. `availableForCampaignId` lists Kenso-sendable inboxes that\n            campaign can assign, replacing `GET /v1/campaigns/{id}/inboxes/available`.\n            A campaign outside the workspace is `not_found`. `isPrimary=true` lists only primary inboxes\n            (owned by a member and on the workspace's primary domain, as `isPrimary` on each inbox),\n            `isPrimary=false` only the rest; it does not combine with `availableForCampaignId`.\n            `role` is `sending`, `replies` or `retired` and lists only inboxes with that `role`;\n            a `replies` or `retired` inbox only receives, so it never appears in an `availableForCampaignId`\n            list and `role` does not combine with it either. A `retired` inbox carries `captureUntil`.\n            Needs Delivery view.",
        "operationId": "inboxes.list",
        "parameters": [
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "AvailableForCampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "IsPrimary",
            "in": "query",
            "description": "true lists only primary inboxes (a member's own mailbox on the workspace's primary domain, as\n`isPrimary` on the model), false only the rest (DEV-1811).",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Role",
            "in": "query",
            "description": "`sending`, `replies` (DEV-3320) or `retired` (DEV-3194): lists only inboxes with that\n            `role`. Combines with `status` and `isPrimary`, not with `availableForCampaignId`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInboxModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "inboxes"
        ],
        "summary": "Connect an SMTP inbox.",
        "description": "Needs Delivery edit.",
        "operationId": "inboxes.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateInboxRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inboxes/bulk-update": {
      "post": {
        "tags": [
          "inboxes"
        ],
        "summary": "Apply one field update to up to 1,000 inboxes.",
        "description": "`paused` pauses or resumes every selected inbox, as on `PATCH /v1/inboxes/{inboxId}`.\n            `profileImageUrl` sets one photo, as on the PATCH, on up to 100 inboxes and takes no other field:\n            `updatedCount` counts the inboxes InboxKit accepted, each other one is in `failed` with the reason.\n            Needs Delivery edit.",
        "operationId": "inboxes.bulk-update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inboxes/{inboxId}": {
      "get": {
        "tags": [
          "inboxes"
        ],
        "summary": "Return one inbox in the current workspace.",
        "description": "Only this read carries `health` (DEV-3672): today's sends against the inbox's cap, its ramp, its warmup\nreadiness and its active blocks. Only for a workspace with the `agent_send` feature flag on; omitted\notherwise, and when it could not be read.",
        "operationId": "inboxes.get",
        "parameters": [
          {
            "name": "inboxId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "inboxes"
        ],
        "summary": "Update an inbox. Absent fields stay unchanged. Null clears text fields and forwarding.",
        "description": "`trackOpens` is the owner's Track opens option and exists only on a member's own mailbox\n            (`ownerMemberId` set); on a shared campaign inbox it is `validation_failed`, and anyone but the\n            owner gets `forbidden`.\n            `paused: true` pauses outreach from the inbox and sets `pausedAt` (kept when it is already\n            paused): campaign steps, triggers and approved Accounts 1:1 email wait instead of sending, and new leads\n            are planned on the campaign's other inboxes. `paused: false` resumes it and clears `pausedAt`;\n            held sends go out on the next dispatch. Warmup, reply sync and replies a member sends keep running, and\n            campaign assignments stay. Needs Delivery edit.\n            `profileImageUrl` (https, not null) sets the sender photo: a `POST /v1/inbox-photos` URL as is, any\n            other fetched once (image-from-URL quota), saved only after InboxKit accepts it. Needs the `inbox_photos`\n            flag, else `400` detail code `feature_disabled`, and an inbox Kenso can set (`profilePhotoSupport``google` or `microsoft`), else `400`; either way nothing is written. InboxKit timing out or failing\n            is `503 service_unavailable`: try again.\n            The update is not atomic: `trackOpens`, then the text fields, then forwarding, then `paused`, then\n            `profileImageUrl` are written in turn, so a failure part-way leaves the earlier ones applied. Each write is\n            idempotent, so retrying the same PATCH is safe.",
        "operationId": "inboxes.update",
        "parameters": [
          {
            "name": "inboxId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inboxes/{inboxId}/verify": {
      "post": {
        "tags": [
          "inboxes"
        ],
        "summary": "Re-check an inbox connection.",
        "description": "Needs Delivery edit.",
        "operationId": "inboxes.verify",
        "parameters": [
          {
            "name": "inboxId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inboxes/{inboxId}/disconnect": {
      "post": {
        "tags": [
          "inboxes"
        ],
        "summary": "Disconnect an inbox connection.",
        "description": "Needs Delivery edit.",
        "operationId": "inboxes.disconnect",
        "parameters": [
          {
            "name": "inboxId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inboxes/{inboxId}/warmup": {
      "get": {
        "tags": [
          "inboxes"
        ],
        "summary": "Return warmup state for one inbox.",
        "description": "`status` and `enabled` come from the live warmup provider's own status, picked in\n            the order pause and resume act on. `status` is `pending` while bought warmup\n            waits to activate, and `paused` when it is paused. An Azure inbox with no warmup\n            subscription is `failed`, because Kenso cannot enroll Azure.\n            `readiness` is the cold-send warmup gate's verdict from provider warmup\n            snapshots: `ready`, `bypassed`, `unconfirmed`, `too_young`,\n            `provider_stale`, or `unavailable`. `enrollmentFailure` (staff only)\n            is why the last pre-warmup provider enrollment failed, its consecutive attempts and\n            the next retry time. Needs Delivery view.",
        "operationId": "inboxes.get-warmup",
        "parameters": [
          {
            "name": "inboxId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxWarmupModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxWarmupModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxWarmupModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "inboxes"
        ],
        "summary": "Pause or resume warmup for one inbox.",
        "description": "`enabled: false` pauses. `enabled: true` resumes. Needs Delivery edit.\n            Neither enrolls a mailbox that has no warmup subscription; staff enroll through\n            `POST /v1/admin/inboxes/warmup/enable` (DEV-1490).",
        "operationId": "inboxes.update-warmup",
        "parameters": [
          {
            "name": "inboxId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxWarmupModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxWarmupModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxWarmupModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/inboxes/{inboxId}/rename": {
      "post": {
        "tags": [
          "inboxes"
        ],
        "summary": "Change an inbox's username, the part of its address before the @.",
        "description": "Only for InboxKit mailboxes (inboxes Kenso bought for you); the domain stays the same. Send the new username\nas `localPart` (`jane.doe`, not the whole address). InboxKit renames the mailbox first; Kenso then\nchanges the inbox's `email`, and, when the inbox already has a sending connection, reconnects it under the\nnew address. `reconnected` says whether that happened, and `warnings` lists any follow-up step that\ndid not finish (the rename itself still succeeded). Renaming to the current username returns the inbox unchanged.\nErrors: `400 validation_failed` on `localPart` (detail code `invalid`, or\n`provider_rejected` when InboxKit refused it; the message is InboxKit's); `409 invalid_state`\n(`not_inboxkit`) for an inbox that is not an InboxKit mailbox; `409 conflict` (`address_in_use`)\nwhen another live inbox has the new address; `503` when InboxKit is not available. Needs Delivery edit\naccess (admins and editors by default). An inbox of another workspace is `404`.",
        "operationId": "inboxes.rename",
        "parameters": [
          {
            "name": "inboxId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenameInboxRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RenameInboxRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RenameInboxRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxRenameModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxRenameModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInboxRenameModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/infra/summary": {
      "get": {
        "tags": [
          "infra"
        ],
        "summary": "Count the workspace's open infra findings.",
        "description": "`openCount` and `bySeverity` count open findings; `snoozedCount` the snoozed ones. `byKind`\n            lists each kind with open findings, with what its subjects cost a month where Kenso knows the price, and\n            `monthlyCostAtStake` sums it. Money is `{ amount (cents), currency: \"usd\" }`. Needs Delivery view and the\n            `infra_findings` flag.\n\nNeeds the `infra_findings` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "infra.summary",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInfraSummaryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInfraSummaryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInfraSummaryModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "infra_findings"
        ]
      }
    },
    "/v1/infra/findings": {
      "get": {
        "tags": [
          "infra"
        ],
        "summary": "List the workspace's infra findings, newest first.",
        "description": "`kind`: billing_leak, provider_cancelled, warmup_missing, idle_domain, domain_expiring, inbox_no_domain,\n            disconnected_inbox. `status`: open (the default), snoozed, ignored, resolved. `severity`: critical,\n            warning, info. Each filter is comma-separated and its values OR together. `evidence` holds what the detector\n            saw; `suggestedAction` names the fix. Needs Delivery view and the `infra_findings` flag.\n\nNeeds the `infra_findings` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "infra.findings",
        "parameters": [
          {
            "name": "Kind",
            "in": "query",
            "description": "Finding kinds, for example `billing_leak,idle_domain`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "description": "`open` (the default), `snoozed`, `ignored`, `resolved`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Severity",
            "in": "query",
            "description": "`critical`, `warning`, `info`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInfraFindingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInfraFindingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfInfraFindingModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "infra_findings"
        ]
      }
    },
    "/v1/infra/findings/{findingId}": {
      "patch": {
        "tags": [
          "infra"
        ],
        "summary": "Snooze, ignore or reopen one of the workspace's infra findings.",
        "description": "Body: `status` is `snoozed` (with `snoozedUntil`, ISO 8601 UTC, in the future and at most a year\nahead), `ignored` or `open` (reopen). A snoozed finding opens again on the first sweep after\n`snoozedUntil`; an ignored one stays ignored until reopened, and the sweep never resolves it. A resolved\nfinding refuses (409 `invalid_state`); another workspace's finding is 404. A `billing_leak` cannot be\nsnoozed or ignored here (403): Kenso pays it and fixes it, and only Kenso staff change it. Records who changed it\nand an audit line in the workspace; changes nothing at a provider. Returns the finding. Needs Delivery edit and\nthe `infra_findings` flag.\n\nNeeds the `infra_findings` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "infra.update-finding",
        "parameters": [
          {
            "name": "findingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInfraFindingRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInfraFindingRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateInfraFindingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInfraFindingModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInfraFindingModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfInfraFindingModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "infra_findings"
        ]
      }
    },
    "/v1/job-post-searches/companies": {
      "post": {
        "tags": [
          "job-post-searches"
        ],
        "summary": "Preview the companies hiring for the job filters.",
        "description": "Body `{ jobFilters }`. Returns one ken-jobs `hiring-companies` page verbatim (the client pages\nwith `jobFilters.cursor` and `jobFilters.limit`) plus `hiringSet: { total, truncated }` for\nthe whole set. ken-jobs 422 codes (`filter_required`, `invalid_cursor`) pass through. Free.",
        "operationId": "job-post-searches.companies",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-post-searches/people": {
      "post": {
        "tags": [
          "job-post-searches"
        ],
        "summary": "Search people at the hiring companies.",
        "description": "Body `{ jobFilters, peopleFilters }`. Forwards `{ ...peopleFilters, accountIds }` to ken-search\nfor the backend user and returns its page plus `hiringSet: { count, truncated }` and, on every\nperson, `jobPost: { title, url, location, postedAt, openRoles, moreRoles }`. An empty hiring set is an\nempty page without a ken-search call. Each person on the page counts one row of the workspace's\n`searchBrowseRows` quota (DEV-3685); past it, 429 `quota_exceeded`.",
        "operationId": "job-post-searches.people",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-post-searches/people/count": {
      "post": {
        "tags": [
          "job-post-searches"
        ],
        "summary": "Count people at the hiring companies.",
        "description": "Same body as `people`, sent with the smallest page. Returns `{ totalResults, hiringSet }`.",
        "operationId": "job-post-searches.count",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-post-searches/import": {
      "post": {
        "tags": [
          "job-post-searches"
        ],
        "summary": "Import people at the hiring companies into a campaign.",
        "description": "Body `{ jobFilters, peopleFilters, campaignId, importLimit }`. Forwards\n`{ campaignId, clientId, peopleFilters: { ...peopleFilters, accountIds }, importLimit }` to ken-search\n`v1/export/campaign` for the backend user, records the five \"Hiring for\" variables per hiring company for\nthe import batches, and returns `{ jobId }`. Poll the job the way the Search Contacts import does.\nAn empty hiring set is 400 `validation_failed` with detail code `empty_hiring_set`. ken-search\nrefusals keep their status (400 `validation_failed`, 403 `forbidden`).",
        "operationId": "job-post-searches.import",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobPostSearchImportResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobPostSearchImportResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobPostSearchImportResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-postings/search": {
      "post": {
        "tags": [
          "job-postings"
        ],
        "summary": "Search job postings.",
        "description": "At least one filter is required (`filter_required`). `limit` 1 to 50, cursor pagination through\n`pagination.next_cursor`. `groupBy: \"company\"` returns one row per company. Free: does not\nuse the export allowance.",
        "operationId": "job-postings.search",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-postings/search/export": {
      "post": {
        "tags": [
          "job-postings"
        ],
        "summary": "Export job postings as JSON or CSV.",
        "description": "Same filters as search, plus `format` (`json` default, or `csv`) and `limit`\n(default 100). The export runs with min(limit, 5000, remaining monthly allowance) rows. The\nmonthly allowance is the workspace's lead limit; exporting does not use lead credits. A larger\nmatch set returns 422 `export_limit_exceeded` with `details[0].count` and\n`details[0].limit`, and uses nothing. Other ken-jobs 422s keep their code and message\n(`filter_required` when no filter is set, `validation_error` when a filter list has more\nthan 100 items) and also use nothing. No allowance left, or rows that no longer fit because\nanother export used them first, returns 402 `plan_limit_reached` with refusal code\n`JOBS_EXPORT_ROWS_LIMIT_REACHED`. Success uses one allowance row per returned row, charged\nonce the whole export is in hand, and sets `X-Ken-Row-Count`. CSV is a file download.\nAn export larger than 512 MB returns 422 `export_too_large` and uses nothing. When too many\nexports are running, returns 503 with `Retry-After`. The returned rows also count on the\nworkspace's `jobsExportRows` fair-use quota (DEV-3685); past it, 429 `quota_exceeded` with\n`Retry-After`, and nothing is used.",
        "operationId": "job-postings.export",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-postings/export-allowance": {
      "get": {
        "tags": [
          "job-postings"
        ],
        "summary": "Get the job-postings export allowance for this calendar month.",
        "description": "Free. The allowance is the workspace's lead limit, in rows per calendar month, and resets on the\nfirst of each month, UTC. Unlimited when the workspace bypasses limits.",
        "operationId": "job-postings.get-export-allowance",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobPostingsExportAllowanceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobPostingsExportAllowanceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobPostingsExportAllowanceModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-postings/{jobPostingId}": {
      "get": {
        "tags": [
          "job-postings"
        ],
        "summary": "Get one job posting with its raw source document and revisions.",
        "description": "Free. Closed postings stay readable.",
        "operationId": "job-postings.get",
        "parameters": [
          {
            "name": "jobPostingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/job-postings/filters/resolve": {
      "post": {
        "tags": [
          "job-postings"
        ],
        "summary": "Resolve partial company, title and location text for filter autocomplete.",
        "description": "Free. Needs no search filter.",
        "operationId": "job-postings.resolve-filters",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs": {
      "get": {
        "tags": [
          "jobs"
        ],
        "summary": "List jobs of one type in the current workspace.",
        "description": "Requires `type` because ids collide across sources. Scraping types are `crawl`, `extraction`, and `batch_scrape`.\nOptional `status` is a comma-separated OR filter. A `knowledge_export` list holds only the caller's own\nexports. A `migration` list is newest first (the cursor is an upper bound); every other type lists oldest first.\nRead-only. Each type also needs what its own routes need: `crawl`, `extraction` and `batch_scrape`\nSearch view, `domain_health` Delivery view, `contact_import`, `lead_scoring` and `enrichment`\nCampaigns view, `contact_export` Campaigns view and the Export feature, `knowledge_export` Knowledge view,\nand `migration` workspace Admin (the Integrations feature). Without it the call is `403 permission_denied`.",
        "operationId": "jobs.list",
        "parameters": [
          {
            "name": "Type",
            "in": "query",
            "description": "`contact_import` or `domain_health`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "description": "Comma-separated statuses: `queued`, `running`, `succeeded`, `failed`, `canceled`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Page size. Default 50, maximum 200.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "description": "Opaque cursor returned as `pagination.nextCursor`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{jobId}": {
      "get": {
        "tags": [
          "jobs"
        ],
        "summary": "Return one job.",
        "description": "Requires `type` because the same numeric id can exist in more than one source.\nAn `inbox_import` job carries `inboxImport` with counts and per-row results; one with no progress\nfor 10 minutes reads `failed` with `error.code``interrupted`.\nA missing or cross-workspace id is `not_found`, and so is another member's `knowledge_export`.\nRead-only. Each type needs what its own routes need, as on the list; without it the call is `403 permission_denied`.\nA scraping job's status read sets `X-Ken-Web-Source` and `X-Ken-Credits-Charged`: Kenso's key charges a job as its reads report progress.\nA crawl or batch scrape returns one Firecrawl status page (about 10 MB at most) per read: when `output.next` is\nnot null, pass it back as `cursor` to read the following page. Other types ignore `cursor`.\nA crawl or batch scrape read draws from the Heavy rate-limit class, like the legacy status routes it replaces.",
        "operationId": "jobs.get",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/jobs/{jobId}/cancel": {
      "post": {
        "tags": [
          "jobs"
        ],
        "summary": "Cancel a job when its type supports cancellation.",
        "description": "Requires Search edit, plus what the type's own routes need, as on the list (a `migration` job: workspace Admin).\nCrawl and batch scrape cancel the stored Firecrawl id. A `migration` job cancels like\n`POST /v1/migration-runs/{runId}/cancel`: it stays `running` until the engine stops it.\nExtraction and the other job types return `409 invalid_state`. A finished scraping or migration job does too.\nA missing job is `not_found`, and so is another member's `knowledge_export`.",
        "operationId": "jobs.cancel",
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/linkedin-accounts": {
      "get": {
        "tags": [
          "linkedin-accounts"
        ],
        "summary": "List LinkedIn accounts in the current workspace.",
        "operationId": "linkedin-accounts.list",
        "parameters": [
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInAccountModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/linkedin-accounts/connect-sessions": {
      "post": {
        "tags": [
          "linkedin-accounts"
        ],
        "summary": "Start a hosted connect or reconnect session.",
        "description": "Omit the account id to connect a new seat. `linkedInAccountId` or `linkedinAccountId` reconnects that\nseat. A client seat (Delivery view, `approve_own_sends`) connects only its own LinkedIn: reconnecting a seat\nanother member connected is `403 forbidden` with `not_your_linkedin`, and a new seat while it holds one is\n`409 conflict` with `reconnect_instead`. Requires Delivery edit, or `approve_own_sends`\n(declared `[WorkspaceMember]`; the action decides, DEV-1811). `importConnections: true` on a new seat\nimports its connections into Accounts once it connects, while `linkedin_connections_import` is on (ignored\notherwise); a reconnect ignores it and keeps the stored setting (DEV-5778).",
        "operationId": "linkedin-accounts.create-connect-session",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLinkedInConnectSessionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLinkedInConnectSessionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateLinkedInConnectSessionRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInConnectSessionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInConnectSessionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInConnectSessionModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/linkedin-accounts/{linkedinAccountId}": {
      "get": {
        "tags": [
          "linkedin-accounts"
        ],
        "summary": "Return one LinkedIn account in the current workspace.",
        "operationId": "linkedin-accounts.get",
        "parameters": [
          {
            "name": "linkedinAccountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInAccountModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInAccountModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInAccountModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "linkedin-accounts"
        ],
        "summary": "Update a LinkedIn account. Absent fields stay unchanged.",
        "description": "Requires Delivery edit access (owners, admins and editors by default). `paused: true` pauses outreach from the account (campaign invites,\nmessages, InMails, profile visits, withdrawals, approved Accounts notes) and sets `pausedAt` (kept when\nit is already paused); `paused: false` resumes it and clears `pausedAt`. Paused actions wait and\nare never failed or moved to email. The autonomous reply agent's sends are held too. A person's replies\nfrom the Inbox and inbox sync keep running. `timezone` takes an IANA id (empty clears it) and\n`workingHoursSchedule` all seven days; invalid values are `400 validation_failed` naming the field.\n`importConnections` switches the seat's connections import (DEV-5778): `400 validation_failed` with\n`feature_off` while `linkedin_connections_import` is off, `403 forbidden` unless the caller connected\nthe seat or is a workspace admin; `importConnectionsChangedAt` moves only when the value changes.",
        "operationId": "linkedin-accounts.update",
        "parameters": [
          {
            "name": "linkedinAccountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLinkedInAccountBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLinkedInAccountBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateLinkedInAccountBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInAccountModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInAccountModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInAccountModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "linkedin-accounts"
        ],
        "summary": "Delete a LinkedIn account.",
        "description": "Returns `204`. Requires Delivery edit access (owners, admins and editors by default).",
        "operationId": "linkedin-accounts.delete",
        "parameters": [
          {
            "name": "linkedinAccountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/lists": {
      "get": {
        "tags": [
          "lists"
        ],
        "summary": "List a campaign's import lists in the current workspace.",
        "description": "Newest first. `limit` and `cursor` page the set. Read-only. Requires `ReadAccess`.",
        "operationId": "lists.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfCampaignListModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/lists/{listId}": {
      "get": {
        "tags": [
          "lists"
        ],
        "summary": "Return one campaign list in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Requires `ReadAccess`.",
        "operationId": "lists.get",
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignListModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "lists"
        ],
        "summary": "Soft-delete a campaign list that no contact references.",
        "description": "A list that still has contacts, including soft-deleted contacts, is `validation_failed`.\nRequires `WriteAccess`.",
        "operationId": "lists.delete",
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfCampaignListModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/markets": {
      "get": {
        "tags": [
          "markets"
        ],
        "summary": "List the market packs.",
        "description": "Every tested and supported pack, ordered by locale: `locale`, `language`, `name`, `status`\n(`tested` passed the quality check, `supported` did not run it yet), and `countries`, the ISO-2\ncodes of the countries one of whose official languages the pack writes (the pack of that exact locale, else the\nlanguage's primary pack). Static: no `X-Ken-Workspace-Id`. Any signed-in caller.",
        "operationId": "markets.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "description": "1 to 200, default 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfMarketSummaryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfMarketSummaryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfMarketSummaryModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/markets/{locale}": {
      "get": {
        "tags": [
          "markets"
        ],
        "summary": "Get one market pack with the cold email notes of its countries.",
        "description": "`locale` is a pack locale such as `fr-FR`, in any case (`FR-fr` and `fr_FR` read as\n            `fr-FR`). A bare language (`fr`), an unknown locale or a draft pack is `404 not_found`.\n            `pack` is the whole pack: formality, salutations, sign-offs, style, banned and spam phrases, examples.\n            `countries` are the countries the pack writes for, each with its languages and `coldEmail`\n            (`regime``opt_out`, `consent` or `unresolved`, `note`, `sources`,\n            `requiresAcknowledgement`). Every note ends with \"Not legal advice.\" Static: no\n            `X-Ken-Workspace-Id`. Any signed-in caller.",
        "operationId": "markets.get",
        "parameters": [
          {
            "name": "locale",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMarketModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMarketModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMarketModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/me": {
      "get": {
        "tags": [
          "me"
        ],
        "summary": "Return the authenticated caller.",
        "description": "Replaces `GET /v1/me/context`, `GET /v1/users/me`, and\n`GET /v1/workspaces/me`. Read-only. Requires `ReadAccess`.\nWhen `X-Ken-Workspace-Id` is present, `role` is the caller's role\nin that workspace. A super admin's role stays `super_admin`.\n`features` is always present: the sorted feature flag keys on for the caller, e.g.\n`[\"accounts\", \"app_v4\"]`. The workspace is `X-Ken-Workspace-Id` when the caller may\nact in it, else the caller's only workspace, else none. Gate UI on it; never on flag rows.\n`permissions` is always present: the caller's effective permissions in that same workspace\n(template, pages, features, account scope, monthly credit limit, credits used this month), narrowed by an\nAPI key's template. It is null for a super admin, when there is no workspace, while the `permissions`\nfeature flag is off for the workspace (the default), or when permissions could not be evaluated (including an\nAPI key that no longer resolves). `hasPaidPlan` is always present: whether that same workspace is on a paid\nplan, null for a super admin, when there is no workspace, or when the plan could not be read.\n`role` is deprecated.",
        "operationId": "me.get",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/meeting-types": {
      "get": {
        "tags": [
          "meeting-types"
        ],
        "summary": "List meeting types.",
        "description": "Every live type in the workspace, oldest first; `ownerMemberId` narrows to one member. The caller's\n            own Intro call is created on first view (never a client seat's). `limit` 1-200 (default 50), `cursor` from `pagination.nextCursor`.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "meeting-types.list",
        "parameters": [
          {
            "name": "OwnerMemberId",
            "in": "query",
            "description": "Only this member's types.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Kind",
            "in": "query",
            "description": "personal, round_robin or collective; comma = OR.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "HostMemberId",
            "in": "query",
            "description": "Types this member hosts (team types list the member as a host).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfMeetingTypeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfMeetingTypeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfMeetingTypeModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      },
      "post": {
        "tags": [
          "meeting-types"
        ],
        "summary": "Create a meeting type.",
        "description": "Starts from the workspace's booking defaults; any field in the body overrides them. `name` is required.\n            `slug` is generated from the name when omitted. The owner's first type becomes their default. Another member's\n            type (`ownerMemberId`) needs the members feature. `round_robin` and `collective` need an admin, a paid plan\n            (402 `plan_limit_reached`, refusal `scheduler_team_meetings`) and `hostMemberIds`. `availability`\n            (DEV-3935) is the type's own schedule for every host, in the shape and rules of the member default on\n            `/v1/me/calendar-preferences` (a schedule here may have no weekly times); `timeZone` null reads it in each\n            host's zone. Omitted or null: each host's own default. Busy time, notice, window, buffers and the daily cap still\n            apply on top. Refusals carry paths such as `availability.weekly.monday[0].end`.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "meeting-types.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMeetingTypeBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMeetingTypeBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateMeetingTypeBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/meeting-types/{meetingTypeId}": {
      "get": {
        "tags": [
          "meeting-types"
        ],
        "summary": "Get a meeting type.",
        "description": "Needs the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "meeting-types.get",
        "parameters": [
          {
            "name": "meetingTypeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      },
      "patch": {
        "tags": [
          "meeting-types"
        ],
        "summary": "Update a meeting type.",
        "description": "Absent fields stay; null clears locationDetail, description, dailyCap, reminderText, questions and\n            availability (back to each host's default; a sent schedule replaces the whole one). A new\n            `slug` keeps the old link redirecting. `isDefault: true` makes it the owner's default. A team type needs an\n            admin and a paid plan; `hostMemberIds` replaces its hosts.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "meeting-types.update",
        "parameters": [
          {
            "name": "meetingTypeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMeetingTypeBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMeetingTypeBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateMeetingTypeBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      },
      "delete": {
        "tags": [
          "meeting-types"
        ],
        "summary": "Delete a meeting type.",
        "description": "Soft delete. Deleting the default promotes the owner's oldest other type. A member's last type cannot be\n            deleted (409 invalid_state, last_personal_type): turn it off instead.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "meeting-types.delete",
        "parameters": [
          {
            "name": "meetingTypeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/meeting-types/{meetingTypeId}/slots": {
      "get": {
        "tags": [
          "meeting-types"
        ],
        "summary": "List a meeting type's open times.",
        "description": "`from` and `to` (required, at most 31 days) bound each slot's start; `timeZone` (IANA) labels\n            `localStartAt`. Status `available`, `no_availability` or `unavailable` with a reason\n            (`host_not_member`, `calendar_not_connected`, `calendar_needs_reconnect`, `calendar_provider_error`,\n            `meeting_type_disabled`). 404 for a team type or one not in the workspace.\n\nNeeds the `scheduler` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "meeting-types.slots",
        "parameters": [
          {
            "name": "meetingTypeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "From",
            "in": "query",
            "description": "Earliest slot start, an ISO-8601 instant. Required.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "To",
            "in": "query",
            "description": "Latest slot start (exclusive), after `from` and at most 31 days later. Required.",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "TimeZone",
            "in": "query",
            "description": "IANA zone that labels each slot's `localStartAt`. Absent means the host's zone.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeSlotsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeSlotsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingTypeSlotsModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "scheduler"
        ]
      }
    },
    "/v1/meetings/{meetingId}/client-brief": {
      "get": {
        "tags": [
          "meetings"
        ],
        "summary": "Return the meeting's prep brief without its credit and write state.",
        "description": "`status` is `ready`, `not_written` or `not_eligible` (`ineligibleReason`: not_account_meeting,\n            no_owner, cancelled, owner_declined, no_external_guest, too_many_guests, already_started). `version`,\n            `writtenAt`, `language`, `authorSource` (ken, agent or user), `isStale` and `staleSince`, and\n            `sections` as GET /v1/meetings/{meetingId}/brief returns them, every line with its `sources`. No credits, no\n            `canWrite` or `canRefresh`, and no write: a member with meetings edit writes or refreshes the brief. Flag\n            `meetings`; meetings view.\n\nNeeds the `meetings` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "meetings.get-client-brief",
        "parameters": [
          {
            "name": "meetingId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingClientBriefModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingClientBriefModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMeetingClientBriefModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "meetings"
        ]
      }
    },
    "/v1/members/{memberId}/permissions": {
      "get": {
        "tags": [
          "members"
        ],
        "summary": "Return a member's permission template, overrides and effective permissions.",
        "description": "`overrides` holds only the differences from the template; `changeCount` counts them. Members read\n            their own; reading someone else's needs the `members` permission (`403 forbidden` otherwise).\n            A user who is not a member of the workspace is `404 not_found`. Behind the `permissions` flag.\n\nNeeds the `permissions` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "members.get-permissions",
        "parameters": [
          {
            "name": "memberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMemberPermissionsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMemberPermissionsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMemberPermissionsModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "permissions"
        ]
      }
    },
    "/v1/outbound-site": {
      "get": {
        "tags": [
          "outbound-site"
        ],
        "summary": "Return the workspace's outbound site.",
        "description": "A read never creates it: a workspace without one gets null fields and `showMainSiteLink: true`.\n`mainSiteUrl`, `brandName`, `contactEmail`, `legalName` and `postalAddress` fill the\npage's slots; `effectiveMainSiteUrl` is `mainSiteUrl`, else the workspace website, and a Kenso brand site\nother than getken.ai (ken.so, getken.dev, ...) becomes the Kenso cold root `https://getken.ai`.\n`currentVersion` is the version every page-mode domain serves (null before the first build).\n`latestRun` is the newest build, with `status``queued`, `running`, `succeeded`,\n`failed` or `canceled`. Requires delivery view.\n\nNeeds the `domain_pages` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "outbound-site.get",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "domain_pages"
        ]
      },
      "patch": {
        "tags": [
          "outbound-site"
        ],
        "summary": "Change the outbound site's fields.",
        "description": "A field left out keeps its value; `null` or a blank string clears a text field. `mainSiteUrl` an absolute\nhttp or https URL (at most 2048), `brandName` and `legalName` at most 200 characters, `contactEmail`\none address, `postalAddress` at most 500, `showMainSiteLink` true or false. A bad field is\n`400 validation_failed` with one detail per field and nothing is saved. The first write creates the outbound\nsite. When a version is live the page updates at once, without a rebuild; if that update fails the change stays\nsaved and the answer is `503 service_unavailable`, so send it again. Example:\n`{\"contactEmail\": \"hello@acme.com\", \"showMainSiteLink\": false}`. Requires delivery edit.\n\nNeeds the `domain_pages` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "outbound-site.update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOutboundSiteRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOutboundSiteRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateOutboundSiteRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "domain_pages"
        ]
      }
    },
    "/v1/outbound-site/refresh": {
      "post": {
        "tags": [
          "outbound-site"
        ],
        "summary": "Rebuild the page from the live website.",
        "description": "Queues a build and answers `202` with the run; the page changes when the run succeeds. An optional\n`note` (at most 1000 characters) is an instruction for the rebuild, such as <c>{\"note\": \"drop the pricing\nsection\"}</c>. `409 run_in_progress` while a build is queued or running; `409 website_missing` when\nneither `mainSiteUrl` nor the workspace website is set. Each queued build counts on the workspace's\n`outboundSiteRefresh` quota: 3 a day and 10 in 30 days. Past it, `429 quota_exceeded` with\n`Retry-After`, the limit in `error.details[0].limit` and the reset time in `quotaResetAt`, repeated\non `error.details[0]` as `resetAt` and `retryAfterSeconds`; nothing is queued. Automatic rebuilds\n(a first page, a website change, a content change) and restores are not counted. Requires delivery edit.\n\nNeeds the `domain_pages` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "outbound-site.refresh",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshOutboundSiteRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshOutboundSiteRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RefreshOutboundSiteRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteRunModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteRunModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteRunModel"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "domain_pages"
        ]
      }
    },
    "/v1/outbound-site/versions": {
      "get": {
        "tags": [
          "outbound-site"
        ],
        "summary": "List the page versions.",
        "description": "Newest first, at most 200, in one page. `isCurrent` marks the live one. Requires delivery view.\n\nNeeds the `domain_pages` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "outbound-site.versions-list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfOutboundSiteVersionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfOutboundSiteVersionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfOutboundSiteVersionModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "domain_pages"
        ]
      }
    },
    "/v1/outbound-site/versions/{versionId}/restore": {
      "post": {
        "tags": [
          "outbound-site"
        ],
        "summary": "Make a version live again.",
        "description": "Adds a `restored` copy of the version, makes it current and updates every page-mode domain at once. Restoring\nthe current version only updates the domains again. `409 version_html_missing` when the version's page is no\nlonger stored. `503 service_unavailable` means send it again; when its message says the live page did not\nupdate, the restore itself was saved. Returns the outbound site. Requires delivery edit.\n\nNeeds the `domain_pages` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "outbound-site.versions-restore",
        "parameters": [
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSiteModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "domain_pages"
        ]
      }
    },
    "/v1/outbound-site/preview": {
      "get": {
        "tags": [
          "outbound-site"
        ],
        "summary": "Return a link to the live page as one domain serves it.",
        "description": "`url` is a signed link on Kenso's edge, valid until `expiresAt` (one hour), that renders the current\n            version with the slots filled for `domainId`; frame it, and fetch a new link before it expires. 404 when the\n            domain is not the workspace's or nothing is published yet; 503 when previews are not configured. Requires delivery\n            view. In a demo workspace, `url` is the filled page itself, a `data:text/html` URL.\n\nNeeds the `domain_pages` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "outbound-site.preview",
        "parameters": [
          {
            "name": "domainId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSitePreviewLink"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSitePreviewLink"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfOutboundSitePreviewLink"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "domain_pages"
        ]
      }
    },
    "/v1/people/intake": {
      "post": {
        "tags": [
          "people"
        ],
        "summary": "Take in one person from your own source: match, place on their company's account, assign an owner.",
        "description": "Body: `email`, `linkedinUrl`, or a name (`fullName`, or `firstName` and `lastName`) with a\nbusiness `companyDomain` (else `400``identity_required`); `title`, `companyName`,\n`phone` (a bad number is `400``invalid_phone`), `source` (`api` default,\n`workflow` or `manual`; any other is `400``invalid_source`), `sourceDetail`,\n`ownerMemberId` (a member, else `400``invalid_member`), `leadStatus` (default `new`),\n`customFields` (person custom field keys; unknown keys are ignored) and `createAccount`. A person with\nthe same email, else LinkedIn URL, else the same name on the domain and no email, is matched: only their blank\nfields fill, pinned fields never change, the phone is added and the latest source updates. Else the person is\ncreated with lead status new and a score. A business domain with no account gets one (stage researching,\nsource inbound, no research credits) unless `createAccount` is false or the workspace's intake settings say\nno; the person joins that account. Owner: the person's, else the account's, the CRM contact's,\n`ownerMemberId`, the workspace default, then the round robin. A new person adds a new_lead row to the\nowner's Today and notifies them. Returns `person`, `created`, `matchedBy` (email, linkedin_url,\nname_domain or none), `accountId`, `accountCreated` and `suggestedDuplicateOfPersonId` (same name\non the domain with another email). A role address (support@, info@, no-reply@) matches the person who holds it but\nnever fills onto one. With a LinkedIn URL or a real first and last name (as on `people.create`) the person\ncomes in without it, matched later by that name on the address's domain, and the answer carries\n`emailDropped: role_address`; with neither and no match it is `422 role_address` and nothing is written. 600 calls an hour per workspace; the next is `429` with\n`Retry-After`. With account scope `own` it is `403``permission_denied` with\n`scope: all`. Behind the `lead_intake` feature (404 when off). Requires `WriteAccess`.\n\nNeeds the `accounts` feature on your workspace. Until it is on, calls answer 404. Needs the `lead_intake` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "people.intake",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntakePersonBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/IntakePersonBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/IntakePersonBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPersonIntakeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPersonIntakeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPersonIntakeModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "accounts",
          "lead_intake"
        ]
      }
    },
    "/v1/permission-templates": {
      "get": {
        "tags": [
          "permission-templates"
        ],
        "summary": "List the workspace's permission templates.",
        "description": "The four built-ins first (Admin, Editor, Viewer, Client), then custom templates by creation. The first call\nfor a workspace stores the built-ins from their defaults, so every template has an id. Never paginated:\na workspace has a handful of templates. Requires workspace membership.\n\nNeeds the `permissions` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "permission-templates.list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPermissionTemplateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPermissionTemplateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPermissionTemplateModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "permissions"
        ]
      }
    },
    "/v1/permission-templates/{templateId}": {
      "get": {
        "tags": [
          "permission-templates"
        ],
        "summary": "Return one permission template.",
        "description": "A template of another workspace is `404 not_found`. Requires workspace membership.\n\nNeeds the `permissions` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "permission-templates.get",
        "parameters": [
          {
            "name": "templateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPermissionTemplateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPermissionTemplateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPermissionTemplateModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "permissions"
        ]
      }
    },
    "/v1/placement-tests": {
      "get": {
        "tags": [
          "placement-tests"
        ],
        "summary": "List placement tests for a campaign, newest first.",
        "description": "Requires `campaignId`. Default sort is `-createdAt`.\nRates are fractions from 0 to 1. Requires `ReadAccess`.\nA campaign outside the workspace is `not_found`.",
        "operationId": "placement-tests.list",
        "parameters": [
          {
            "name": "CampaignId",
            "in": "query",
            "description": "Campaign whose placement tests to list.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Page size. Defaults to 50. Maximum 200.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "description": "Opaque cursor from a previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPlacementTestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPlacementTestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPlacementTestModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "placement-tests"
        ],
        "summary": "Start an inbox placement test for a campaign.",
        "description": "Requires Delivery edit. Exactly one of `domainId` or `inboxId` is required\nunless `randomScope` is true. Example:\n`{ \"campaignId\": 812, \"inboxId\": 44 }`. Kenso pays for each test, so each call counts against a\nper-workspace budget: `placementTestCreates` (5 a minute, 20 a day, 50 in 30 days; a Free plan gets 1, 2\nand 5), over it `429 rate_limited` with `Retry-After`. Where `placement_tests_public` is on, the\nbudget is `placementTestCreatesPublic` (2 a day, 8 in 30 days, on every plan), over it\n`429 quota_exceeded` naming the limit, with `Retry-After`. Super admins are exempt.\n`openPixel: true` sends the copy with the campaign open pixel on `link.` or `unsub.` of the\ntest's sending domain, whichever serves it; `openPixelHost` names the host used. No serving host, plain-text\ncopy, or a test with the other pixel setting already running for the campaign and domain is\n`409 invalid_state`.",
        "operationId": "placement-tests.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePlacementTestRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePlacementTestRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePlacementTestRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPlacementTestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPlacementTestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPlacementTestModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/placement-tests/{placementTestId}": {
      "get": {
        "tags": [
          "placement-tests"
        ],
        "summary": "Return one placement test with its full results.",
        "description": "Adds what the list leaves out: `type`, `startedAt`, `sentCount`, `senderInboxIds`, the\n`subject` and `body` sent, `counts`, per `providers`, per `senders`, per `seeds`\n(masked addresses), InboxKit `errors`, and up to 10 `earlierTests` of the test's own campaign and\ndomain (whichever are set) for a trend; a shared weekly test trends with the campaign that owns it, and an inbox\ntest without a domain has none. Result fields are omitted until the test completes. Rates are fractions from 0\nto 1.\nRequires `ReadAccess`. A test outside the workspace is `not_found`.",
        "operationId": "placement-tests.get",
        "parameters": [
          {
            "name": "placementTestId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPlacementTestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPlacementTestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPlacementTestModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/prompt-versions": {
      "get": {
        "tags": [
          "prompt-versions"
        ],
        "summary": "List prompt versions for a segment in the current workspace.",
        "description": "A segment outside `X-Ken-Workspace-Id` is `not_found` before versions are read. Requires `ReadAccess`.",
        "operationId": "prompt-versions.list",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPromptVersionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPromptVersionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPromptVersionModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/prompt-versions/{versionId}": {
      "get": {
        "tags": [
          "prompt-versions"
        ],
        "summary": "Return one prompt version for a segment in the current workspace.",
        "description": "A missing segment or version is `not_found`. Requires `ReadAccess`.",
        "operationId": "prompt-versions.get",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptVersionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptVersionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptVersionModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/prompt-versions/{versionId}/restore": {
      "post": {
        "tags": [
          "prompt-versions"
        ],
        "summary": "Restore a prompt version for a segment in the current workspace.",
        "description": "Qualification and scoring workflow sync stay inside the existing revert command.\nA segment outside the workspace is `not_found` before the write.\n`dryRun` returns what the restore would clear and does not write. A restore that would clear\ncampaign AI output returns `409 conflict` with `error.impact` until `confirm` is true.\nThe body is optional. Requires `WriteAccess`.",
        "operationId": "prompt-versions.restore",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestorePromptVersionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RestorePromptVersionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RestorePromptVersionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptVersionRestoreModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptVersionRestoreModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptVersionRestoreModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/prompts": {
      "get": {
        "tags": [
          "prompts"
        ],
        "summary": "List prompts in the current workspace.",
        "description": "Ordered by id. Optional `campaignId`, `segmentId`, and `flow` narrow the page.\n`q` matches the name. Requires `ReadAccess`.",
        "operationId": "prompts.list",
        "parameters": [
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "SegmentId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Flow",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPromptModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPromptModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfPromptModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "prompts"
        ],
        "summary": "Create a prompt in the current workspace.",
        "description": "Returns `201` and `Location`. `campaignId` or `segmentId` is required so the\nprompt stays in the workspace. `confirm=true` is required when the write would refresh\ncached AI results. Requires `WriteAccess`.",
        "operationId": "prompts.create",
        "parameters": [
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePromptRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePromptRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreatePromptRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/prompts/{promptId}": {
      "get": {
        "tags": [
          "prompts"
        ],
        "summary": "Return one prompt in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Requires `ReadAccess`.",
        "operationId": "prompts.get",
        "parameters": [
          {
            "name": "promptId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "prompts"
        ],
        "summary": "Update a prompt.",
        "description": "Absent fields stay unchanged. JSON null clears a text field or `promptTemplateId`.\n`segmentId` cannot change on this route, and `campaignId` cannot be cleared on a prompt\nwithout a segment (`400`: it would belong to no workspace).\n`confirm=true` is required when the write would refresh cached AI results.\nRequires `WriteAccess`.",
        "operationId": "prompts.update",
        "parameters": [
          {
            "name": "promptId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "prompts"
        ],
        "summary": "Delete a prompt.",
        "description": "Returns `204`. `confirm=true` is required when deletion would refresh cached AI results.\nRequires `WriteAccess`.",
        "operationId": "prompts.delete",
        "parameters": [
          {
            "name": "promptId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "confirm",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/prompts/test": {
      "post": {
        "tags": [
          "prompts"
        ],
        "summary": "Run a prompt test against live model calls.",
        "description": "Samples contacts in the campaign and runs the requested flow. This spends model usage.\nA missing campaign is `not_found`. Requires `PromptTestAccess`.",
        "operationId": "prompts.test",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestPromptRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TestPromptRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TestPromptRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptTestResultModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptTestResultModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfPromptTestResultModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/reply-templates": {
      "get": {
        "tags": [
          "reply-templates"
        ],
        "summary": "List reply templates in the current workspace.",
        "description": "Ordered by id. Requires `ReadAccess`.",
        "operationId": "reply-templates.list",
        "parameters": [
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfReplyTemplateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfReplyTemplateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfReplyTemplateModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "reply-templates"
        ],
        "summary": "Create a reply template.",
        "description": "The author is the caller: `user` for a person in the dashboard, `agent` for an agent,\nan MCP token or an API key. `authorSource``agent` only lowers a person to `agent`.\nRequires Inbox edit access and the workspace settings permission (owners, admins and editors by default).",
        "operationId": "reply-templates.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReplyTemplateRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReplyTemplateRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateReplyTemplateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/reply-templates/{replyTemplateId}": {
      "get": {
        "tags": [
          "reply-templates"
        ],
        "summary": "Return one reply template in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Requires `ReadAccess`.",
        "operationId": "reply-templates.get",
        "parameters": [
          {
            "name": "replyTemplateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "reply-templates"
        ],
        "summary": "Update a reply template.",
        "description": "Only the fields sent are written; absent fields keep their stored value. JSON null clears `description`.\nThe author is the caller, as on create, and a person's write records `user`.\nAn agent, an MCP token or an API key cannot edit a human-written template. Requires Inbox edit access and the workspace settings permission (owners, admins and editors by default).",
        "operationId": "reply-templates.update",
        "parameters": [
          {
            "name": "replyTemplateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfReplyTemplateModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "reply-templates"
        ],
        "summary": "Delete a reply template.",
        "description": "Returns `204`. The author is the caller, as on create.\nAn agent, an MCP token or an API key cannot delete a human-written template. Requires Inbox edit access and the workspace settings permission (owners, admins and editors by default).",
        "operationId": "reply-templates.delete",
        "parameters": [
          {
            "name": "replyTemplateId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "authorSource",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/saved-list-invites/{token}": {
      "get": {
        "tags": [
          "saved-list-invites"
        ],
        "summary": "Read a saved-list invite.",
        "description": "The list's name, kind and member count, the owner workspace's name and the invite `status`\n(`pending`, `accepted` or `revoked`). No `X-Ken-Workspace-Id` needed. An unknown token or a\ndeleted list is `404`.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-list-invites.get",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListInviteModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListInviteModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListInviteModel"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-list-invites/{token}/accept": {
      "post": {
        "tags": [
          "saved-list-invites"
        ],
        "summary": "Accept a saved-list invite into a workspace.",
        "description": "No body. The list becomes readable (read-only) in the `X-Ken-Workspace-Id` workspace. The signed-in user's\nemail must be the invited address (`403` otherwise). An invite is accepted once (`409 invalid_state`);\nthe owner workspace cannot accept its own list (`409 invalid_state`); a workspace that already holds the list\ngets `409 conflict`; a revoked invite is `404`. Requires the Search page at edit in that workspace.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-list-invites.accept",
        "parameters": [
          {
            "name": "token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListGrantModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListGrantModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListGrantModel"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/members": {
      "get": {
        "tags": [
          "saved-lists"
        ],
        "summary": "List a saved list's members.",
        "description": "Members in id order. `limit` 1-100 (default 50); `cursor` is the previous page's `nextCursor`.\n`country`, `seniority`, `industry` and `headcountBand` match the stored value exactly (take\nthem from the list's `counts` breakdowns); `title` matches a part of the title, any case;\n`hasSendableEmail` is true or false. Opted-out members never show. `includeTotal=true` adds\n`pagination.total`, the filtered count; with no filter on a library list it is the list's stored member count,\nthe same number as `counts.members`. A member never carries an email or a phone: `emailCount` and\n`phoneCount` say how many the list holds, an email identity key shows as `em:` plus the member id, and a\ncustom field holding an email or a phone is left out. Each member on the page counts one row of the workspace's\n`apiReadRows` quota; past it, 429 `quota_exceeded`. Requires the Search page (view).\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.list-members",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Country",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Seniority",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Title",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Industry",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "HeadcountBand",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "HasSendableEmail",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IncludeTotal",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListMemberModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListMemberModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListMemberModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/members/{memberId}": {
      "delete": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Remove a member from a saved list.",
        "description": "Own lists only: a list shared with the workspace, a library list, another user's private list or a member of\nanother list is 404. Recounts the list. 204 on success. Requires the Search page (edit).\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.remove-member",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "memberId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists": {
      "get": {
        "tags": [
          "saved-lists"
        ],
        "summary": "List saved lists.",
        "description": "`scope`: `own` (default; the workspace's lists, private ones only for their owner user), `shared`\n            (lists other workspaces shared with this one through an accepted invite) or `library` (approved library\n            lists). `kind` (`people` or `companies`), `q` (name contains, any case) and `icpTag` (one\n            tag, exact) filter; `slug` with `scope=library` returns the one library list with that slug, or none.\n            `limit` 1-100 (default 50) and `cursor` page the list in id order; `pagination.total` counts every\n            match. On a shared or library list each source shows its type, status and counts but not its parameters.\n            Requires search view.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.list",
        "parameters": [
          {
            "name": "Scope",
            "in": "query",
            "description": "own (default), shared or library.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Kind",
            "in": "query",
            "description": "people or companies.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "description": "Case-insensitive contains on the list name.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IcpTag",
            "in": "query",
            "description": "One ICP tag, matched exactly.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Slug",
            "in": "query",
            "description": "A library list's slug; with scope=library only, and the other filters do not apply.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "1 to 100, default 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      },
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Create a saved list.",
        "description": "Body: `name` (1-200), `kind` (`people` or `companies`), optional `description` (up to\n2000), `visibility` (`workspace`, the default, or `private`: only you see it; needs a signed-in\nuser) and `icpTags` (up to 20, each up to 50 characters). The list starts empty and belongs to you. Returns\n`201`. Requires search edit.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}": {
      "get": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Get a saved list.",
        "description": "A list of this workspace, a list shared with it through an accepted invite, or an approved library list, with its\ncounts and sources. Anything else is `404`. Requires search view.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.get",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      },
      "patch": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Update a saved list.",
        "description": "Any of `name`, `description` (`null` clears it), `visibility` (`workspace` or\n`private`; only the list's owner can make it private) and `icpTags` (`[]` clears them). Absent\nfields stay. Only this workspace's lists; a shared or library list is `404`. Requires search edit.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.update",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSavedListBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSavedListBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSavedListBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      },
      "delete": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Delete a saved list.",
        "description": "Soft delete of one of this workspace's lists. A library copy approved from it stays. Returns `204`. A shared\nor library list is `404`. Requires search edit.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.delete",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/copy": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Copy a saved list into a new list of this workspace.",
        "description": "Copies any list you can read (your own, one shared with you, or a library list) into a new `workspace` list\nthat belongs to you. Optional body: `name` (default \"<name> (copy)\") and `memberFilters`\n(`country`, `seniority`, `title` contains, `industry`, `headcountBand`,\n`hasSendableEmail`) to copy only matching members. Opted-out members are never copied. At most 500,000\nmembers (`400 too_many_members`). Returns `201` with the new list. Requires search edit.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.copy",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CopySavedListBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CopySavedListBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CopySavedListBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/invites": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Invite an email address to a saved list.",
        "description": "Body `{email}`. Creates a read-only grant with status `pending` and emails the address a link\n(`https://app.ken.so/lists/accept/{token}`); the invitee picks which of their workspaces receives the list.\nA list with CSV-uploaded members needs `POST /v1/saved-lists/{savedListId}/rights-confirmation` first, else\n`409 rights_confirmation_required`. A private list cannot be shared (`409 invalid_state`). A second\ninvite to an address with a pending invite on the list is `409 conflict`. The grant is created even when the\nemail cannot be sent. Returns `201`. Requires the Search page at edit and the share feature.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.create-invite",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListInviteBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListInviteBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListInviteBody"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListGrantModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListGrantModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListGrantModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/grants": {
      "get": {
        "tags": [
          "saved-lists"
        ],
        "summary": "List a saved list's grants.",
        "description": "Every grant of one of the workspace's lists, pending, accepted and revoked, in id order (`hasMore` is always\nfalse). An accepted or revoked grant names the receiving workspace. Requires the Search page at view.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.list-grants",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListGrantModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListGrantModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSavedListGrantModel"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/grants/{grantId}": {
      "delete": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Revoke a saved-list grant.",
        "description": "Status `revoked`: the receiving workspace stops reading the list; contacts it already copied into campaigns\nstay. Revoking a revoked grant is fine. Returns `204`. Requires the Search page at edit and the share feature.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.revoke-grant",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "grantId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/rights-confirmation": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Confirm the right to share a saved list's uploaded data.",
        "description": "The owner confirms \"I have the right to share this data\" for a list with CSV-uploaded members; sharing and library\nsubmission need it. Records who and when (the latest confirmation wins) and returns the list. Needs a user (a\nsession or an API key that belongs to a user), else `403`. Requires the Search page at edit and the share\nfeature.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.confirm-rights",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListRightsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListRightsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListRightsModel"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/sources": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Add a source to a saved list.",
        "description": "Body `{ sourceType, parameters }`. `search_filters`: a people-search body (paging keys are dropped, at\nleast one filter is required); `search_selection`: `{ personIds }`, 1 to 1,000 picked people;\n`saved_search`: `{ savedSearchId }`, resolved as you each time it runs; `campaign`:\n`{ campaignId }`, the campaign's contacts (also needs campaigns view); `list`: `{ savedListId }`,\nanother list you can read. A company list takes only a list source; a list has at most 50 sources. Returns\n`202` with the source in `pending`; poll it until `done` or `failed` (`statusMessage`\nsays why). Requires search edit.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.create-source",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListSourceBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListSourceBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSavedListSourceBody"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/sources/{sourceId}": {
      "get": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Get one source of a saved list.",
        "description": "Poll this after adding or refreshing a source: `status` is `pending`, `running`, `done` or `failed`, `lastRefreshAdded` counts the members the last run added. Requires search view.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.get-source",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "sourceId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/sources/{sourceId}/refresh": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Refresh one Search source of a saved list.",
        "description": "Re-runs a `search_filters`, `search_selection` or `saved_search` source and adds new matches; members\nthat no longer match stay. A campaign or list source answers 400 `not_refreshable`. Returns `202` with the\nsource. Requires search edit.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.refresh-source",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "sourceId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/refresh": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Refresh every Search source of a saved list.",
        "description": "Re-runs the list's Search sources and adds new matches; campaign, list and CSV sources are not re-run and no member is removed. Returns `202` with the Search sources. Requires search edit.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.refresh",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "minimum": 1,
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfIReadOnlyListOfSavedListSourceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfIReadOnlyListOfSavedListSourceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfIReadOnlyListOfSavedListSourceModel"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/submissions": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Submit a list to the library.",
        "description": "Puts one of the workspace's own lists in `libraryState``submitted`, credited to the workspace and the\nsigned-in person, for a Kenso review. Nothing reaches the library until staff approve it; approval copies the list,\nso later edits change only the workspace's list and the owner resubmits. `icpTags` and `description`\nreplace the list's when given. 409 `rights_confirmation_required` while the list holds uploaded CSV data (or\na CSV upload is still running) without a rights confirmation; 409 `already_submitted` while a submission\nwaits. A list of another workspace, a list shared with this workspace, a library list and another member's private\nlist are 404. Needs Search edit, the share permission and a signed-in person (a workspace API key is 403).\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.submit",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitSavedListBody"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitSavedListBody"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SubmitSavedListBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSubmissionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSubmissionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSubmissionModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-lists/{savedListId}/uploads": {
      "post": {
        "tags": [
          "saved-lists"
        ],
        "summary": "Add a CSV's rows to a saved list.",
        "description": "Multipart: the CSV in field `file` (at most 400 MB and 100,000 rows) and, optionally, `columnMappings`: the\nJSON array the contact-import upload takes, for example\n`[{\"csvColumn\":\"Email\",\"targetField\":\"email\"},{\"csvColumn\":\"Deal size\",\"targetField\":\"custom_variable\",\"customVariableName\":\"deal_size\"}]`.\nWithout it the columns map by their headers, as on the campaign upload. Kenso checks the file and answers 202 with a\n`csv` source in `pending`, then adds the rows in the background: read the source until it is `done` or\n`failed`; its `parameters` then carry `rowCount`, `inserted`, `merged` and `rejected`\n(rows with no LinkedIn URL, email or name and company domain; for a company list, no domain or company page).\nUploaded emails enter unverified, every phone is kept, and personal columns (birth date, gender, age, personal email\nand the like) are never stored. Only the workspace's own lists: a shared or library list is 404. Requires Search edit\nand the Import feature.\n\nNeeds the `saved_lists` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "saved-lists.create-upload",
        "parameters": [
          {
            "name": "savedListId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSavedListSourceModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "saved_lists"
        ]
      }
    },
    "/v1/saved-searches": {
      "get": {
        "tags": [
          "saved-searches"
        ],
        "summary": "List the saved searches you can see in this workspace.",
        "description": "Your own and the ones shared with you. `limit` (1-100, default 50) and `cursor` page the list.",
        "operationId": "saved-searches.list",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "saved-searches"
        ],
        "summary": "Save a search.",
        "description": "Body: `name`, `searchType` (`people` or `companies` as Search names them),\n`filtersJson` and `isShared`. The saved search belongs to you, in this workspace.",
        "operationId": "saved-searches.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/saved-searches/{savedSearchId}": {
      "get": {
        "tags": [
          "saved-searches"
        ],
        "summary": "Get one saved search.",
        "operationId": "saved-searches.get",
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "saved-searches"
        ],
        "summary": "Update a saved search.",
        "description": "Body: any of `name`, `filtersJson` and `isShared`. Absent fields stay as they are.",
        "operationId": "saved-searches.update",
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "saved-searches"
        ],
        "summary": "Delete a saved search.",
        "operationId": "saved-searches.delete",
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/saved-searches/{savedSearchId}/run": {
      "post": {
        "tags": [
          "saved-searches"
        ],
        "summary": "Run a saved search.",
        "description": "Runs the saved filters and returns `{ savedSearchId, searchType, totalResults, results }`. Each profile on the\npage counts one row of the workspace's `searchBrowseRows` quota (DEV-3685); past it, 429 `quota_exceeded`.",
        "operationId": "saved-searches.run",
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/saved-searches/{savedSearchId}/share": {
      "post": {
        "tags": [
          "saved-searches"
        ],
        "summary": "Share a saved search, or stop sharing it.",
        "description": "Body: `action` (`grant` or `revoke`), `targetType`, `targetId` and\n`permission`, as Kenso Search defines them.",
        "operationId": "saved-searches.share",
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scheduled-messages/{scheduledMessageId}/cancel": {
      "post": {
        "tags": [
          "scheduled-messages"
        ],
        "summary": "Cancel a scheduled message that has not started sending.",
        "description": "Requires `InboxReplyAccess`. A missing id is `not_found`.\nA row that is already sending, sent, cancelled, or failed is `invalid_state`.\nCancel still returns the scheduled message when restoring the composer draft fails,\nwith `draft.saved` false so the caller saves the draft again.",
        "operationId": "scheduled-messages.cancel",
        "parameters": [
          {
            "name": "scheduledMessageId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scraping/scrape": {
      "post": {
        "tags": [
          "scraping"
        ],
        "summary": "Scrape one public URL.",
        "description": "A page served from Kenso's archive is free and counts one unit of the workspace's `webArchiveReads` quota\n(DEV-3685); past it, 429 `quota_exceeded` with `Retry-After`. A call through a customer's own MCP\nconnection (`X-Ken-Mcp-Connection: customer`) first counts one `webReadCalls` unit (DEV-5234).",
        "operationId": "scraping.scrape",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scraping/map": {
      "post": {
        "tags": [
          "scraping"
        ],
        "summary": "Map a site's public URLs.",
        "description": "A call through a customer's own MCP connection (`X-Ken-Mcp-Connection: customer`) counts one\n`webReadCalls` unit (DEV-5234); past it, 429 `quota_exceeded` with `Retry-After`.",
        "operationId": "scraping.map",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scraping/search": {
      "post": {
        "tags": [
          "scraping"
        ],
        "summary": "Search the web.",
        "operationId": "scraping.search",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scraping/crawls": {
      "post": {
        "tags": [
          "scraping"
        ],
        "summary": "Start a crawl and return a job.",
        "description": "Requires `ReadAccess`. The response is `202` with a `crawl` job.\nPoll `GET /v1/jobs/{jobId}?type=crawl`. Cancel with `POST /v1/jobs/{jobId}/cancel?type=crawl`.\nSSRF rejection stays in the Firecrawl service. The body needs a `limit` of 1 to 1,000 pages.\nWhen the job cannot be recorded, the started crawl is stopped and the answer is `503 service_unavailable`.",
        "operationId": "scraping.create-crawl",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scraping/extractions": {
      "post": {
        "tags": [
          "scraping"
        ],
        "summary": "Start an extraction and return a job.",
        "description": "Requires `ReadAccess`. The response is `202` with an `extraction` job.\nPoll `GET /v1/jobs/{jobId}?type=extraction`. Extraction cannot be canceled.",
        "operationId": "scraping.create-extraction",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/scraping/batch-scrapes": {
      "post": {
        "tags": [
          "scraping"
        ],
        "summary": "Start a batch scrape and return a job.",
        "description": "Requires `ReadAccess`. The response is `202` with a `batch_scrape` job.\nPoll `GET /v1/jobs/{jobId}?type=batch_scrape`. Cancel with `POST /v1/jobs/{jobId}/cancel?type=batch_scrape`.",
        "operationId": "scraping.create-batch-scrape",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJobModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/people": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Search the people index.",
        "description": "Returns ken-search's people page. Each person also carries `hasKenEmail`: true when Kenso already holds a\nverified email for the person's LinkedIn profile, so importing them costs no email find on a paid plan.\n`kenEmailStatus` (DEV-6935) labels the best address Kenso holds: `none`, `risky`, `catch_all` or\n`verified`. It labels only: no filter, no sort, and no address in the answer.\nLookalikes (needs the workspace's `lookalikes` feature, else 403 `feature_disabled`):\n`companyLookalike` finds people at companies like the seeds (<c>{seeds: [{companyId} | {domain} |\n{linkedInUrl} | {text}], negatives, mode: precise | broad, minGrade: 1-5, excludeDomains,\nincludeNonB2b}</c>, 1-100 seeds); `lookalike` finds people like seed people (<c>{seeds: [{personId} |\n{linkedInUrl}], negatives, mode, minGrade, includeSeedCompanies}</c>, 1-50 seeds). Not both (400\n`lookalike_conflict`). Kenso adds the workspace's do-not-contact and customer domains to\n`excludeDomains`. `minGrade` is a whole number from 1 to 5 (default 2): precise mode drops rows graded\nbelow it, broad mode keeps every row. Rows then sort by similarity, each carries `lookalike: {score, grade}`\n(score 0-100, grade 1-5 with 5 best), and the page carries `lookalikeSeeds: {resolved, unresolved}`. Errors:\n400 `lookalikes_unavailable`, `too_many_seeds`, `invalid_lookalike` (also a `minGrade` that\nis not 1-5, such as a letter); 422 `no_usable_seeds` with `lookalikeSeeds`. A\nlookalike search is a snapshot: stored searches refuse it (400 `lookalike_not_storable`).\n`view` (DEV-7245): `full` (the default) returns each person's whole profile; `summary` keeps only the\nfields a list row needs (names, headline, LinkedIn URL, photo, current title, company and its size and funding,\nlocation, seniority, function, the job-change signals, `hasKenEmail`, `kenEmailStatus`,\n`lookalike`), 1-2 KB a person instead of 17-28 KB. Get the full record with get-person. Any other value\nis 400 `validation_failed`.",
        "operationId": "search.search-people",
        "parameters": [
          {
            "name": "view",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/people/{personId}": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Get one person by index id.",
        "description": "The person carries `hasKenEmail` and `kenEmailStatus`, as in people search.",
        "operationId": "search.get-person",
        "parameters": [
          {
            "name": "personId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/people/lookup": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Look up a person by LinkedIn profile URL.",
        "description": "The person carries `hasKenEmail` and `kenEmailStatus`, as in people search.",
        "operationId": "search.lookup-person",
        "parameters": [
          {
            "name": "linkedInUrl",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/people/facets": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Get facet counts for a people search.",
        "operationId": "search.get-people-facets",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/companies": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Search the company index. The upstream path remains accounts.",
        "description": "Lookalikes (needs the workspace's `lookalikes` feature, else 403 `feature_disabled`): send\n<c>lookalike: {seeds: [{companyId} | {domain} | {linkedInUrl} | {text}], negatives: [{companyId} | {domain} |\n{linkedInUrl}], mode: precise | broad, minGrade: 1-5, excludeDomains: [...], includeNonB2b}</c>, 1-100\nseeds and 0-100 negatives, a text seed up to 4,000 characters. Kenso adds the workspace's do-not-contact and\ncustomer domains to `excludeDomains` (10,000 at most, yours first). Rows then sort by similarity\n(`sortBy` is ignored, at most 2,000 results through the usual paging), each carries\n`lookalike: {score, grade}` (score 0-100, grade 1-5 with 5 best), and the page carries\n`lookalikeSeeds: {resolved, unresolved}`. `minGrade` is a whole number from 1 to 5 (default 2): precise\nmode drops rows graded below it, broad mode keeps every row. Errors: 400 `lookalikes_unavailable`,\n`too_many_seeds`, `invalid_lookalike` (also a `minGrade` that is not 1-5); 422 `no_usable_seeds` with\n`lookalikeSeeds`. A lookalike search is a snapshot: stored searches refuse it (400\n`lookalike_not_storable`), so save or import its results as a selection of ids.",
        "operationId": "search.search-companies",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/companies/{companyId}": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Get one company by index id.",
        "operationId": "search.get-company",
        "parameters": [
          {
            "name": "companyId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/companies/lookup": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Look up a company by LinkedIn company URL.",
        "operationId": "search.lookup-company",
        "parameters": [
          {
            "name": "linkedInUrl",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/companies/facets": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Get facet counts for a company search.",
        "operationId": "search.get-company-facets",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/filters": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Get the filter catalog.",
        "operationId": "search.get-filters",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/metadata": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Get the filter metadata catalog, or one category's values.",
        "description": "Without `category` this returns the whole catalog as one resource. With `category` it returns a\nlist of that category's values: `q` filters them, `limit` (1-100, default 50) and\n`cursor` page them, and `includeTotal=true` adds `pagination.totalCount`. A cursor that\ndid not come from `pagination.nextCursor` is 400 `validation_failed`.",
        "operationId": "search.get-metadata",
        "parameters": [
          {
            "name": "Category",
            "in": "query",
            "description": "A filter category, for example `industries`. Without it the whole catalog is returned.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "description": "Contains-text filter on the category's values. Used only with `category`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Page size, 1-100. Default 50. Used only with `category`.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IncludeTotal",
            "in": "query",
            "description": "Adds `pagination.totalCount`, the number of values in the category that match `q`.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/companies/people": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Search people who work at the given companies.",
        "description": "Body: a people search plus `companyIds`, the company index ids to search in. Returns ken-search's\npeople page; each person carries `hasKenEmail` and `kenEmailStatus`, as in people search. Takes\n`companyLookalike` and `lookalike` exactly as people search does, behind the same `lookalikes`\nfeature.",
        "operationId": "search.search-company-people",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "422": {
            "description": "Unprocessable Content",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/headcount-changes": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "List companies whose headcount grew.",
        "description": "Filters: `month` (`yyyy-MM`, detection month; all months, newest first, without it) and\n`minGrowthPct`. `limit` (1-100, default 50) and `cursor` page the list.",
        "operationId": "search.list-headcount-changes",
        "parameters": [
          {
            "name": "Month",
            "in": "query",
            "description": "Detection month as `yyyy-MM`. Without it every month is returned, most recent first.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "MinGrowthPct",
            "in": "query",
            "description": "Only companies that grew by at least this percentage, for example `20` for 20%.",
            "schema": {
              "type": "number",
              "format": "double"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Page size, 1-100. Default 50.",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "description": "The `pagination.nextCursor` of the previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/people/expand-titles": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Expand job titles into related titles.",
        "description": "The body is ken-search's title expansion request and is forwarded as is. Each expansion is a model call: the\nsame body in the same workspace is answered from the last hour's result, and anything else takes one unit of\nthe workspace's `aiSearchExpand` quota (20 a minute, 500 a day, shared with industry expansion, every\ncaller kind). Past it, 429 `quota_exceeded` with `Retry-After`.",
        "operationId": "search.expand-titles",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/metadata/expand-industries": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Expand industries into related industries.",
        "description": "The body is ken-search's industry expansion request (up to 50 industries) and is forwarded as is. Cached and\nmetered like title expansion, on the same `aiSearchExpand` quota.",
        "operationId": "search.expand-industries",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/lookalike-seeds": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "List seed suggestions for a lookalike search.",
        "description": "`source` (required): `customers` (the workspace's customer accounts, `count` 1 per account),\n            `crm` (companies on CRM deals: opportunities and synced CRM deals, `count` is deals), `interested`\n            (companies whose people replied Interested, `count` is distinct contacts), `replies` (companies whose\n            people sent any real reply: every class but Automated, HardBounce, SoftBounce, OutOfOffice and NDR, `count`\n            is distinct contacts), `campaign` (companies of one campaign's live leads, `count` is contacts) or\n            `website_visitors` (companies behind human visits to the workspace's tracked website, `count` is\n            visits). `crm_won` is still accepted as `crm` with `stage=won`. `stage` (`crm` only):\n            `won` (default), `open` (neither won nor lost) or `any`. `campaignId`: required with\n            `campaign`, an optional filter with `interested` and `replies`; it also needs Campaigns view (403\n            `permission_denied` without it), and a campaign outside the workspace, or deleted, is 404 `not_found`. `since` (`interested`, `replies`, `website_visitors`): a\n            `YYYY-MM-DD` day (UTC); only replies or visits on or after it count. A parameter the source does not take is\n            400 `validation_failed`. Replies, campaign leads and visits are read newest first, at most 20,000, then\n            grouped by company domain (the contact's company domain, else the address's domain); a free mail domain never\n            becomes a seed. Each row is `{domain, name, count}`. Up to 200 rows, ordered by `count` descending then\n            `domain`, in one page. An empty list is normal. Free. Needs the workspace's `lookalikes` feature (404\n            while it is off), and Accounts view on top of the controller's Search view: the rows are the workspace's\n            customers, deals, replies, leads and visitors, which the accounts, opportunities and CRM routes keep behind\n            Accounts view.\n\nNeeds the `lookalikes` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "search.list-lookalike-seeds",
        "parameters": [
          {
            "name": "source",
            "in": "query",
            "description": "Required: `customers`, `crm`, `interested`, `replies`, `campaign` or\n`website_visitors`. `crm_won` is still accepted, as `crm` with `stage=won`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stage",
            "in": "query",
            "description": "`crm` only: `won` (default), `open` (neither won nor lost) or `any`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "campaignId",
            "in": "query",
            "description": "Required with `campaign`; an optional filter with `interested` and `replies`.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "since",
            "in": "query",
            "description": "`interested`, `replies` and `website_visitors`: a day as `YYYY-MM-DD` (UTC); only replies or\n            visits on or after it count.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/LookalikeSeedListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LookalikeSeedListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/LookalikeSeedListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "lookalikes"
        ]
      }
    },
    "/v1/search/imports": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Import Search people into a campaign.",
        "description": "Body: `campaignId` plus exactly one of `personIds` (the people to import) or\n`searchFilters` (a people search; every match is imported, up to `limit`). Returns 202 with\nthe import job, `{ jobId, status }`; poll `GET /v1/search/imports/{importId}`. A campaign\noutside the workspace is 404 `not_found`. Needs a member role or higher, and the Search page (the import\nruns a Search query); reading an import's status needs only Campaigns view.",
        "operationId": "search.create-import",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSearchImportRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSearchImportRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSearchImportRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "search"
        ],
        "summary": "List a campaign's most recent import.",
        "description": "`campaignId` is required. Returns the campaign's latest import as a list of zero or one item; there\n            is never a next page. A campaign outside the workspace is 404 `not_found`.",
        "operationId": "search.list-imports",
        "parameters": [
          {
            "name": "campaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/imports/preview": {
      "post": {
        "tags": [
          "search"
        ],
        "summary": "Preview a Search import: how many of its people Kenso already holds an email for.",
        "description": "Body: the selection a create would send, without `campaignId`: exactly one of `personIds` or\n`searchFilters` (with `limit`, 5,000 when absent). Returns <c>{ personCount, checkedCount,\nkenEmailCount }</c>: the people the import would take, the people checked (the first 500 Search returns, in import\norder) and how many of those Kenso already holds a verified email for. On a paid plan an address Kenso already holds\ncosts no email find. Imports nothing and counts no Search quota. Needs Campaigns view and the Search page.",
        "operationId": "search.preview-import",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewSearchImportRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewSearchImportRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewSearchImportRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSearchImportPreview"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSearchImportPreview"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSearchImportPreview"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/imports/{importId}": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Get one import job.",
        "description": "Returns ken-search's import status. ken-search is always asked for the resolved workspace and answers 404\n`not_found` for an import from another workspace.",
        "operationId": "search.get-import",
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/search/sample": {
      "get": {
        "tags": [
          "search"
        ],
        "summary": "Get the workspace's sample search.",
        "description": "Answers at once and never waits for a build. `status`: `ready` (the sample; `refreshing` true\nwhile a rebuild runs because the ICP changed or the sample expired), `pending` (nothing cached yet and a\nbuild is queued or running; poll again in about 5 seconds), `unavailable` (no ICP context yet, or the last\nbuild for this ICP failed: retried after 10 minutes when the model or a search was down, after 6 hours when it\nfound nothing; also when the workspace ran its 6 builds of the day with no sample to serve) or `off` (the `search_sample` flag is off; nothing runs). A ready sample holds `query` (the filters it searched) and the tabs `profiles` and\n`companies` (`{ request, page }`, page as `POST /v1/search/people` and `/companies` answer),\n`jobs` (`{ request: { jobFilters, peopleFilters }, companies, people }`, as\n`/v1/job-post-searches` answers) and `funding` (`{ request: { signalType, parameters }, page }`, as\n`POST /v1/triggers/preview` answers). A tab is absent when its search failed or found nothing. The sample is\ncached for 7 days (10 minutes when a tab failed on an outage) and rebuilt, at most 6 times a day, when the website, the company context or the ICP Knowledge file changes. Requires\nSearch view.",
        "operationId": "search.get-sample",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSearchSampleResource"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSearchSampleResource"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSearchSampleResource"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/segments": {
      "get": {
        "tags": [
          "segments"
        ],
        "summary": "List segments of a campaign in the current workspace.",
        "description": "Ordered by id. `q` matches the name. `isActive` filters that flag.\n`includeMetrics=false` skips the contact counts and omits `contactCount`,\n`rawContactCount` and `readyContactCount`: use it when only ids and names are needed.\nRead-only. Requires `ReadAccess`.",
        "operationId": "segments.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsActive",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IncludeMetrics",
            "in": "query",
            "description": "Default true. False skips the contact counts (`contactCount`, `rawContactCount`,\n`readyContactCount` are omitted): a names-only read for pickers.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSegmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSegmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSegmentModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "segments"
        ],
        "summary": "Create a segment on a campaign in the current workspace.",
        "description": "Returns `201` and `Location`. Requires `WriteAccess`.",
        "operationId": "segments.create",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSegmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSegmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSegmentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/segments/preview": {
      "post": {
        "tags": [
          "segments"
        ],
        "summary": "Preview a segment filter against the campaign.",
        "description": "Returns the match count, a contact sample, and the filter catalog (`filterOptions`).\nOmit the body to read the catalog only, or read it without a campaign at `GET /v1/segments/filter-options`.\nA body, including an empty object, runs the match preview.\n`segmentId` scopes a match preview to an existing segment.\nRead-only. Requires `ReadAccess`.",
        "operationId": "segments.preview",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "segmentId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaDTO"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaDTO"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaDTO"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentPreviewModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentPreviewModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentPreviewModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}": {
      "get": {
        "tags": [
          "segments"
        ],
        "summary": "Return one segment in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Requires `ReadAccess`.",
        "operationId": "segments.get",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "segments"
        ],
        "summary": "Update a segment.",
        "description": "Absent fields stay unchanged. JSON null clears `description` and `abTestPercentage`.\nRequires `WriteAccess`.",
        "operationId": "segments.update",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSegmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSegmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateSegmentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "segments"
        ],
        "summary": "Soft-delete a segment.",
        "description": "Moves the segment's contacts to Default (or the remaining A/B buckets) and soft-deletes the\nsegment's email sequence, LinkedIn steps and prompts with it. Returns `400 validation_failed`\nwhen its contacts would move to Default and the segment has an email or LinkedIn sequence that\nneither Default nor the campaign root has. Requires Campaigns edit access (owners, admins and editors by default).\nReturns `204`.",
        "operationId": "segments.delete",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/segments/{segmentId}/activate": {
      "post": {
        "tags": [
          "segments"
        ],
        "summary": "Activate a segment.",
        "description": "Idempotent when the segment is already active. Requires `WriteAccess`.",
        "operationId": "segments.activate",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/deactivate": {
      "post": {
        "tags": [
          "segments"
        ],
        "summary": "Deactivate a segment.",
        "description": "Idempotent when the segment is already inactive. Requires `WriteAccess`.",
        "operationId": "segments.deactivate",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/versions": {
      "get": {
        "tags": [
          "segments"
        ],
        "summary": "List saved versions of a segment, newest first.",
        "description": "`limit` is 1 to 100 and defaults to 20. `cursor` is the opaque cursor from the previous page.\n            Requires `ReadAccess`.",
        "operationId": "segments.list-versions",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSegmentVersionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSegmentVersionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSegmentVersionModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "segments"
        ],
        "summary": "Save a segment as a new version.",
        "description": "Applies the body to the segment and writes one version row. The body takes the\n`PATCH /v1/segments/{segmentId}` fields plus `sourceVersionId`. Absent fields keep the live\nsegment's value, or the `sourceVersionId` version's value when one is given, so a save with no body saves\nthe current state. JSON null clears `description` and `abTestPercentage`. A\n`sourceVersionId` of another segment is `not_found`, and another save in progress for the segment is\n`409 conflict`. When the save lands but version history is not captured, `version` is null and\n`versionWarning` says so. Requires `WriteAccess`.",
        "operationId": "segments.save-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveSegmentVersionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveSegmentVersionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SaveSegmentVersionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentVersionSaveModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentVersionSaveModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentVersionSaveModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/versions/{versionId}": {
      "get": {
        "tags": [
          "segments"
        ],
        "summary": "Return one segment version and its snapshot.",
        "description": "`segmentationType` and `status` on the snapshot are lowercase snake_case.\n            Requires `ReadAccess`.",
        "operationId": "segments.get-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentVersionDetailModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentVersionDetailModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentVersionDetailModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/versions/{versionId}/restore": {
      "post": {
        "tags": [
          "segments"
        ],
        "summary": "Restore a segment to a saved version.",
        "description": "`dryRun` returns the cascade preview and does not write. Each child includes the\n            resolved `snapshot` the revert dialog renders.\n            An applying restore that would clear campaign AI output returns `409 conflict`\n            with `error.impact` until `confirm` is true. Cascade `kind` and `status` are lowercase snake_case.\n            Requires `WriteAccess`.",
        "operationId": "segments.restore-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreSegmentVersionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreSegmentVersionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RestoreSegmentVersionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentRestoreModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentRestoreModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentRestoreModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/filter-options": {
      "get": {
        "tags": [
          "segments"
        ],
        "summary": "Return the segment filter catalog.",
        "description": "The values a segment filter accepts: seniority levels, functions, industries, company types, employment types,\nfunding rounds, technologies, email validity, email providers and languages, each as `value`,\n`label` and an optional `category`. The catalog is the same for every workspace and is the\n`filterOptions` object `POST /v1/campaigns/{campaignId}/segments/preview` returns; this read needs no\ncampaign. It replaces `GET /v1/campaigns/segments/filter-metadata`. Read-only. Requires\n`ReadAccess`.",
        "operationId": "segments.get-filter-options",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentFilterMetadataDTO"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentFilterMetadataDTO"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSegmentFilterMetadataDTO"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sending-capacity/forecast": {
      "get": {
        "tags": [
          "sending-capacity"
        ],
        "summary": "Forecast the current workspace's email sends for UTC today and the next two days: what its healthy inboxes\ncan send per day (capacity), what is already queued or planned (planned), and what is left (remaining).\nPublic, read only, Delivery view. Takes no what-if inputs; the staff forecast keeps those.",
        "operationId": "sending-capacity.get-forecast",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSendingCapacityForecastModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSendingCapacityForecastModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSendingCapacityForecastModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/email-sequence": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return the campaign email sequence.",
        "operationId": "email-sequences.get",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "sequences"
        ],
        "summary": "Replace the campaign email sequence.",
        "description": "Creates the sequence when none exists. Requires `SequenceEditAccess`. A link the URL reputation check\nrefuses is 400 `validation_failed` with one `link_reputation_blocked` detail per link: `field``steps[i].subject` or `steps[i].body`, `rule`, `stepOrder` and, for a saved step, `stepId`.\nSend `expectedModifiedAt` (the `modifiedAt` from your last read) so an edit made since is not overwritten.",
        "operationId": "email-sequences.replace",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceEmailSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceEmailSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceEmailSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              }
            }
          },
          "409": {
            "description": "`conflict` with detail code `stale_write` on `expectedModifiedAt`: the sequence changed since your read, or it no longer exists. Read it again and resend.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "sequences"
        ],
        "summary": "Delete the campaign email sequence.",
        "operationId": "email-sequences.delete",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/segments/{segmentId}/email-sequence": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return the segment email sequence.",
        "operationId": "segment-email-sequences.get",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "sequences"
        ],
        "summary": "Replace the segment email sequence.",
        "description": "Same refusals as the campaign email sequence replace, `link_reputation_blocked` and the\n`expectedModifiedAt` check included.",
        "operationId": "segment-email-sequences.replace",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceEmailSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceEmailSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceEmailSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceModel"
                }
              }
            }
          },
          "409": {
            "description": "`conflict` with detail code `stale_write` on `expectedModifiedAt`: the sequence changed since your read, or it no longer exists. Read it again and resend.",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "sequences"
        ],
        "summary": "Delete the segment email sequence.",
        "operationId": "segment-email-sequences.delete",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/linkedin-sequence": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return the campaign LinkedIn sequence.",
        "operationId": "linkedin-sequences.get",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "sequences"
        ],
        "summary": "Replace the campaign LinkedIn sequence.",
        "description": "Requires Campaigns edit access (owners, admins and editors by default).",
        "operationId": "linkedin-sequences.replace",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/linkedin-sequence": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return the segment LinkedIn sequence.",
        "operationId": "segment-linkedin-sequences.get",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "sequences"
        ],
        "summary": "Replace the segment LinkedIn sequence.",
        "operationId": "segment-linkedin-sequences.replace",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ReplaceLinkedInSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sequence-variables": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return the sequence variable catalog.",
        "description": "Pass `campaignId` to include that campaign's custom variables.\nRequires `ReadAccess`.",
        "operationId": "sequence-variables.get",
        "parameters": [
          {
            "name": "campaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceVariablesModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceVariablesModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceVariablesModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/email-sequence/preview": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Preview the campaign email sequence for one contact.",
        "description": "Requires `ReadAccess`. Variable types are lowercase snake_case. Each step shows the text dispatch sends the\ncontact: a contact routed to another language gets the approved localization with its `language`, English\n`mirrorSubject` and `mirrorBody`, and `qaScore`. `language` previews as a contact in that\nlanguage instead. Pass `contactId`, or `useRandom=true` to preview a random contact of the campaign;\nwith neither the call is `400 validation_failed` on `contactId`. A contact outside the campaign, or a\ncampaign with no contacts to pick, is `404 not_found`. `senderEmailId` previews from that inbox of the\ncampaign, as the test send sends from it: its names, signature and unsubscribe host fill the steps, and\n`sender` names it. Without it, or with an inbox the campaign does not use, the first sender by email fills them.",
        "operationId": "email-sequences.preview",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "contactId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "useRandom",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "language",
            "in": "query",
            "description": "DEV-1922: preview as a contact in this language (fr-FR, de) gets the steps; omitted previews in the contact's own\nlanguage. The campaign's source language previews the source text.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "senderEmailId",
            "in": "query",
            "description": "DEV-6632: the inbox to preview from, as the test send's `senderEmailId`: its names, signature and\nunsubscribe host fill the steps, and `sender` names it. An inbox that is not one of the campaign's, or\nnone, previews from the first sender.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequencePreviewModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequencePreviewModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequencePreviewModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/email-sequence/preview": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Preview the segment email sequence for one contact.",
        "description": "Pass `contactId`, or `useRandom=true` to preview a random contact of the segment; with neither the call\nis `400 validation_failed` on `contactId`. `senderEmailId` works as on the campaign preview.",
        "operationId": "segment-email-sequences.preview",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "contactId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "useRandom",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "language",
            "in": "query",
            "description": "DEV-1922: preview as a contact in this language (fr-FR, de) gets the steps; omitted previews in the contact's own\nlanguage. The campaign's source language previews the source text.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "senderEmailId",
            "in": "query",
            "description": "DEV-6632: the inbox to preview from, as the test send's `senderEmailId`: its names, signature and\nunsubscribe host fill the steps, and `sender` names it. An inbox that is not one of the campaign's, or\nnone, previews from the first sender.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequencePreviewModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequencePreviewModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequencePreviewModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/email-sequence/test-send": {
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Send the campaign email sequence to test recipients.",
        "description": "`targetEmails` takes at most 5 valid addresses, none on the workspace blocklist or hard bounced. Once the\n            campaign has inboxes, `senderEmailId` must be one of them. Each recipient x step counts against the\n            workspace's daily test-send emails (429 when used up). Requires `SequenceEditAccess`. Each step goes out as\n            dispatch sends it to the contact, in the contact's language or in `language`; `notes` names a step\n            sent as an approved translation.",
        "operationId": "email-sequences.test-send",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestSendSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TestSendSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TestSendSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceTestSendModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceTestSendModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceTestSendModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/email-sequence/test-send": {
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Send the segment email sequence to test recipients.",
        "description": "The recipient, sender and quota rules of the campaign test send apply.",
        "operationId": "segment-email-sequences.test-send",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestSendSequenceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TestSendSequenceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TestSendSequenceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceTestSendModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceTestSendModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceTestSendModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/email-sequence/versions": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "List saved versions of a segment email sequence, newest first.",
        "description": "`limit` is 1 to 100 and defaults to 20. Requires `ReadAccess`.",
        "operationId": "segment-email-sequences.list-versions",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Save a new segment email sequence version.",
        "description": "Omit `steps` to snapshot the live sequence. With `sourceVersionId`, omitted or empty\n`steps` keep that version's steps, and a non-empty list overlays them.\nA link the URL reputation check refuses is 400 `validation_failed` with one `link_reputation_blocked`\ndetail per link (`field`, `stepId`, `stepOrder`, `rule`, `url`), as on the sequence replace.\nRequires `SequenceEditAccess`.",
        "operationId": "segment-email-sequences.save-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveEmailSequenceVersionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveEmailSequenceVersionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SaveEmailSequenceVersionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceVersionSaveModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceVersionSaveModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceVersionSaveModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/email-sequence/versions/{versionId}": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return one segment email sequence version.",
        "operationId": "segment-email-sequences.get-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceVersionDetailModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceVersionDetailModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfEmailSequenceVersionDetailModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/email-sequence/versions/{versionId}/restore": {
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Restore a segment email sequence to a saved version.",
        "description": "A link the URL reputation check refuses is 400 `validation_failed` with one `link_reputation_blocked`\ndetail per link; its `field` is `steps.subject` or `steps.body` and `stepId` is the live\nstep the restore would overwrite. Requires `SequenceEditAccess`.",
        "operationId": "segment-email-sequences.restore-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/linkedin-sequence/versions": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "List saved versions of a campaign LinkedIn sequence, newest first.",
        "operationId": "linkedin-sequences.list-versions",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Save a new campaign LinkedIn sequence version.",
        "description": "Omit `steps` to snapshot the live lane. With `sourceVersionId`, omitted or empty\n`steps` keep that version's steps, and a non-empty list overlays them.\nRequires Campaigns edit access (owners, admins and editors by default).",
        "operationId": "linkedin-sequences.save-version",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveLinkedInVersionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveLinkedInVersionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SaveLinkedInVersionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionSaveModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionSaveModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionSaveModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/linkedin-sequence/versions/{versionId}": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return one campaign LinkedIn sequence version.",
        "operationId": "linkedin-sequences.get-version",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionDetailModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionDetailModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionDetailModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/linkedin-sequence/versions/{versionId}/restore": {
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Restore a campaign LinkedIn sequence to a saved version.",
        "description": "Requires Campaigns edit access (owners, admins and editors by default).",
        "operationId": "linkedin-sequences.restore-version",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/linkedin-sequence/versions": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "List saved versions of a segment LinkedIn sequence, newest first.",
        "operationId": "segment-linkedin-sequences.list-versions",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfSequenceVersionModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Save a new segment LinkedIn sequence version.",
        "description": "Omit `steps` to snapshot the live lane. With `sourceVersionId`, omitted or empty\n`steps` keep that version's steps, and a non-empty list overlays them.\nRequires Campaigns edit access (owners, admins and editors by default).",
        "operationId": "segment-linkedin-sequences.save-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveLinkedInVersionRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveLinkedInVersionRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SaveLinkedInVersionRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionSaveModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionSaveModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionSaveModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/linkedin-sequence/versions/{versionId}": {
      "get": {
        "tags": [
          "sequences"
        ],
        "summary": "Return one segment LinkedIn sequence version.",
        "operationId": "segment-linkedin-sequences.get-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionDetailModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionDetailModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfLinkedInSequenceVersionDetailModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/segments/{segmentId}/linkedin-sequence/versions/{versionId}/restore": {
      "post": {
        "tags": [
          "sequences"
        ],
        "summary": "Restore a segment LinkedIn sequence to a saved version.",
        "description": "Requires Campaigns edit access (owners, admins and editors by default).",
        "operationId": "segment-linkedin-sequences.restore-version",
        "parameters": [
          {
            "name": "segmentId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "versionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSequenceRestoreModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/shares": {
      "get": {
        "tags": [
          "shares"
        ],
        "summary": "List the workspace's share links, newest first.",
        "description": "Filters: `campaignId`, `accountId` (shares with that account's plan) and `status`\n(comma-separated: not_opened, viewed, n_of_m_approved, changes_requested, approved). Revoked shares\nare left out. `changesRequestedCount` counts every live share with changes requested, whatever\nthe filters. `url` is empty unless the caller has Share page edit and the `share` feature.\nRequires the Share page.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "description": "Only the shares of this campaign.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "AccountId",
            "in": "query",
            "description": "Only the shares with this account's plan.",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "description": "Comma-separated: not_opened, viewed, n_of_m_approved, changes_requested, approved.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ShareListResponse"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareListResponse"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareListResponse"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "share"
        ]
      },
      "post": {
        "tags": [
          "shares"
        ],
        "summary": "Create a share link.",
        "description": "Body: `items` (one or more of leads, copy, settings, icp, report, plan), `campaignId`\n(required unless only plans), `accountIds` (1-100, required with plan), `permission`\n(view, comment, approve), `expiry` (7_days, 30_days default, never), `recipients` (up to\n20), `holdLaunch` (approve plus leads, copy or settings), `recurringReport` (with report),\noptional `name` (defaults to \"<campaign> · <items>\") and `company` (defaults to the\nworkspace name). Freezes each item's snapshot now. Copy is one item and leads one item per active\nsegment; on an approve share they are the workspace's own external approval items, so a decision on\nthe share also satisfies the launch gate. A campaign with no copy or no active segment answers\n400 with an `items` detail coded `empty`. Every recipient emailed counts against the workspace's\ndaily share email cap: past it the create answers `429 quota_exceeded` (detail code\n`share_email_quota`) and creates nothing. Requires Share page edit and the `share` feature.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShareInput"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShareInput"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShareInput"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "share"
        ]
      }
    },
    "/v1/shares/preview": {
      "post": {
        "tags": [
          "shares"
        ],
        "summary": "Preview a share before creating it, as the reviewer will see it.",
        "description": "Takes the body of `POST /v1/shares` and answers the public payload of `GET /v1/public/shares/{token}`\nfor the share it would create, from the same snapshot builders: copy rendered for sample leads, the lead\nlists, settings, ICP, report and account plans. Saves nothing and emails no one. Items are numbered from 1\nand not reviewed, except copy and lead lists of an approve share whose version is already approved. Answers\nwhat create answers for a bad body. Requires Share page edit and the `share` feature.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.preview-draft",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShareInput"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShareInput"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateShareInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSharePublicModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSharePublicModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSharePublicModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "share"
        ]
      }
    },
    "/v1/shares/{shareId}": {
      "get": {
        "tags": [
          "shares"
        ],
        "summary": "Get a share link with its items, comments, access rows and log.",
        "description": "`url` is empty unless the caller has Share page edit and the `share` feature. Requires the Share page.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.get",
        "parameters": [
          {
            "name": "shareId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "share"
        ]
      },
      "patch": {
        "tags": [
          "shares"
        ],
        "summary": "Update a share link. Absent fields stay unchanged.",
        "description": "Fields: `name`, `company`, `recipients` (replaces the list), `expiry` (counted from\ncreation), `holdLaunch`, `recurringReport`. What is shared and the permission are fixed:\ncreate a new share to change them. Each email address `recipients` adds counts against the workspace's\ndaily share email cap, since it gets the later reminders and weekly reports: past it the update answers\n`429 quota_exceeded` (`share_email_quota`) and changes nothing. Requires Share page edit and the\n`share` feature.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.update",
        "parameters": [
          {
            "name": "shareId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateShareInput"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateShareInput"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateShareInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "share"
        ]
      },
      "delete": {
        "tags": [
          "shares"
        ],
        "summary": "Revoke a share link.",
        "description": "The link then answers `410 share_inactive`. Decisions already made stay. Returns `204`.\nRequires Share page edit and the `share` feature.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.revoke",
        "parameters": [
          {
            "name": "shareId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        },
        "x-ken-features": [
          "share"
        ]
      }
    },
    "/v1/shares/{shareId}/reminders": {
      "post": {
        "tags": [
          "shares"
        ],
        "summary": "Remind the share's recipients.",
        "description": "Emails the link to every recipient that is an email address again and logs `share_reminder_sent`.\nReturns `202` with `recipientCount`, the addresses emailed. An expired share answers\n`410 share_expired`; a share without recipients `400`; a share whose recipients are only\nnames `409 no_email_recipients`. One reminder per share every 24 hours: another within that answers\n`429 quota_exceeded` (detail code `reminder_cooldown`) with `Retry-After`, and so does a\nreminder past the workspace's daily share email cap (`share_email_quota`). Nothing is sent then.\nRequires Share page edit and the `share` feature.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.remind",
        "parameters": [
          {
            "name": "shareId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareReminderModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareReminderModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfShareReminderModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "share"
        ]
      }
    },
    "/v1/shares/{shareId}/preview": {
      "get": {
        "tags": [
          "shares"
        ],
        "summary": "Preview the share as the reviewer sees it.",
        "description": "The public payload of `GET /v1/public/shares/{token}`, without counting a view. Works on an expired share. Requires the Share page.\n\nNeeds the `share` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "shares.preview",
        "parameters": [
          {
            "name": "shareId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSharePublicModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSharePublicModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSharePublicModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "share"
        ]
      }
    },
    "/v1/signals": {
      "post": {
        "tags": [
          "signals"
        ],
        "summary": "Queue signals for the current workspace.",
        "description": "Requires Search edit access (owners, admins and editors by default). `type` and `source` are lowercase snake_case.\nNon-super-admins are forced to synthetic signals and send at most 100 signals a call,\neach counted against the workspace's signal quota. A contact, campaign, or segment\noutside the workspace is rejected before publish. `duplicateCount` counts signals\nskipped because their `dedupKey` was queued in the last 24 hours.",
        "operationId": "signals.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSignalsRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSignalsRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSignalsRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSignalIntakeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSignalIntakeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfSignalIntakeModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tags": {
      "get": {
        "tags": [
          "tags"
        ],
        "summary": "List tag definitions in the current workspace.",
        "description": "`entityType` (campaign, contact, mailbox, domain, reply, account, linkedin_account, person) lists the\n            tags that can go on that type: every user tag, plus system tags and sender configs whose scope includes it.\n            With `entityId`, the list is the tags assigned to that campaign, contact, mailbox, domain, account,\n            LinkedIn account, or person. `systemKey` lists only the workspace's system tag with that key,\n            created on first use: `systemKey=champion` returns the Champion tag a person carries to be watched for\n            a job change (DEV-4281). Reply and LinkedIn conversation assignments use\n            `POST /v1/tags/{tagId}/assignments`. `includeUsage=true` adds `usage` to each tag:\n            live assignment counts in this workspace (`campaignCount`, `contactCount`,\n            `replyCount` for email messages, `linkedinConversationCount`, `inboxCount`,\n            `domainCount`, `accountCount`, `linkedinAccountCount`). Without it `usage` is absent.\n            `entityType=campaign&includeEntityIds=true` adds `entityIds` to each tag: the ids of the workspace's\n            live campaigns carrying it, so every campaign's tags take one call (DEV-5179). Another `entityType` with it is\n            `400 validation_failed`; without it `entityIds` is absent.",
        "operationId": "tags.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "EntityType",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "EntityId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "IncludeUsage",
            "in": "query",
            "description": "true adds `usage` (assignment counts per entity type) to every tag on the page.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IncludeEntityIds",
            "in": "query",
            "description": "With `entityType=campaign`, true adds `entityIds` (the live campaigns carrying it) to every tag on the page.",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "SystemKey",
            "in": "query",
            "description": "Only the workspace's system tag with this key, created on first use (DEV-4281): `champion` finds the\nChampion tag for people.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTagModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTagModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTagModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "tags"
        ],
        "summary": "Create a tag definition.",
        "description": "Requires the workspace settings permission (owners, admins and editors by default). `entityTypes` (campaign, contact, mailbox, domain, reply, account,\nlinkedin_account, person) is the scopes the tag lists under; omitted or empty means every scope. Any tag that is not a\nsystem tag can be assigned to any entity type whatever its scopes. A name already used in the\nworkspace (case-insensitive) is `400 validation_failed`. `color` defaults to\n`#E4D0FF`.",
        "operationId": "tags.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTagRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tags/{tagId}": {
      "get": {
        "tags": [
          "tags"
        ],
        "summary": "Get one tag definition.",
        "operationId": "tags.get",
        "parameters": [
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "tags"
        ],
        "summary": "Update a tag definition.",
        "description": "Absent fields stay unchanged. `null` description clears it. Requires the workspace settings permission (owners, admins and editors by default).",
        "operationId": "tags.update",
        "parameters": [
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "tags"
        ],
        "summary": "Delete a tag definition.",
        "description": "Soft-deletes the definition and its assignments. Requires the workspace settings permission (owners, admins and editors by default).",
        "operationId": "tags.delete",
        "parameters": [
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/tags/{tagId}/assignments": {
      "post": {
        "tags": [
          "tags"
        ],
        "summary": "Assign a tag to an entity.",
        "description": "`entityType` is `campaign`, `contact`, `mailbox`, `domain`, `account`, or\n            `linkedin_account` or `person` with `entityId`. `reply` uses `messageId`.\n            `linkedin_conversation` uses `conversationId`. A tag that is not a system tag can be assigned to any\n            entity type; a system tag only to its scopes. Assigning a tag the entity already has succeeds and changes\n            nothing. An entity outside the workspace, or a deleted one, is `404 not_found`. Mailbox, domain and\n            LinkedIn account tags need Delivery edit; person tags need Accounts edit, like account tags. The route itself\n            needs workspace membership.",
        "operationId": "tags.assign",
        "parameters": [
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TagAssignmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TagAssignmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TagAssignmentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "tags"
        ],
        "summary": "Remove a tag assignment.",
        "description": "Query parameters, not a body: `entityType` plus `entityId`, `messageId`, or\n`conversationId`. A missing `entityType` is `validation_failed`.\nThe route needs workspace membership; the entity type adds its page edit access, as on assign.",
        "operationId": "tags.unassign",
        "parameters": [
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "EntityType",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "EntityId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "MessageId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ConversationId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tags/{tagId}/assignments/bulk-create": {
      "post": {
        "tags": [
          "tags"
        ],
        "summary": "Assign a tag to up to 1,000 entities in one call.",
        "description": "Each item has the shape of the single assignment body. Items run one at a time in request order\nthrough the same path as `POST /v1/tags/{tagId}/assignments`. An entity outside the workspace\nis `not_found` and is not written. `results` is in request order; `status` is\n`assigned`, `not_found`, `validation_failed`, or `failed`. The whole request is\nrejected, with nothing written, when `items` is empty, has more than 1,000 entries, or has a\nnull entry. A tag outside the workspace is `404`. The route needs workspace membership; each item's entity type adds its page edit access, as on assign.",
        "operationId": "tags.bulk-assign",
        "parameters": [
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkTagAssignmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkTagAssignmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkTagAssignmentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tags/{tagId}/assignments/bulk-delete": {
      "post": {
        "tags": [
          "tags"
        ],
        "summary": "Remove a tag from up to 1,000 entities in one call.",
        "description": "Same body, validation, and per-item behavior as `bulk-create`, through the same path as\n`DELETE /v1/tags/{tagId}/assignments`. A successful item is `removed`.\nThe route needs workspace membership; each item's entity type adds its page edit access, as on assign.",
        "operationId": "tags.bulk-unassign",
        "parameters": [
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkTagAssignmentRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkTagAssignmentRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/BulkTagAssignmentRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTagAssignmentBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads/counts": {
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "Count inbox threads by tab and source.",
        "description": "Requires Inbox view. Email and LinkedIn together. `status`, `folder`,\n`isArchived` and `isSaved` name the tab the way `GET /v1/threads` takes them,\nand `allCount` is the number of distinct threads that list returns for the tab. The\nlist's `pagination.total` counts email messages, so it is higher when a thread has\nseveral messages in the tab. `accountsCount` and\n`campaignsCount` split the tab by account-linked and campaign threads, and\n`campaigns` lists every campaign with a thread in the inbox. `toReplyCount`,\n`unreadCount`, `latestMessageAt` and `inboxChangedAt` ignore the tab filters.\n`inboxChangedAt` moves when a reply arrives (a late-synced one included) or changes tab,\nfor example when the classifier files it; poll it and refetch the list when it changes. An email thread is counted once however many messages it\nhas; a LinkedIn conversation is one thread.",
        "operationId": "threads.counts",
        "parameters": [
          {
            "name": "Status",
            "in": "query",
            "description": "Inbox tab token: to_reply, other, automated_reply, not_interested, human_reply.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Folder",
            "in": "query",
            "description": "Inbox folder: inbox, sent, or all. Omitted means inbound.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsArchived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IsSaved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadCountsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadCountsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadCountsModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads/mark-all-read": {
      "post": {
        "tags": [
          "threads"
        ],
        "summary": "Mark every unread thread in the inbox read.",
        "description": "Requires Inbox edit, like `PATCH /v1/threads/{threadId}`. Takes no body. Marks every unread\ninbound email message and every unread LinkedIn conversation the inbox shows, in one pass,\nand returns how many changed. Safe to retry: a repeat call returns `updatedCount: 0`.",
        "operationId": "threads.mark-all-read",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMarkAllThreadsReadModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMarkAllThreadsReadModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfMarkAllThreadsReadModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads": {
      "post": {
        "tags": [
          "threads"
        ],
        "summary": "Start an email thread to one person from a shared cold inbox.",
        "description": "For an agent or API key (DEV-3672). Dark: `404` until the `agent_send` flag is on for the workspace.\n`Idempotency-Key` (1 to 200 characters) is required. A retry with the same key and request returns the\noriginal message with `201` and sends nothing; the key with another request is\n`409 idempotency_key_reused`; a send still in flight is `409 in_progress` with `Retry-After: 30`;\na send the provider never confirmed is `409 outcome_unknown` and is never resent: read the inbox's threads\nwith the person before sending again under a new key.\nThe send goes through the agent guardrails and the inbox's day cap. Until a host registers the guardrails (PR A-3)\nevery send is refused with `503 agent_guardrails_unavailable` and nothing is reserved or written. A refusal\nis the canonical error whose\n`details[0].code` is the reason, `fix` says what to do, and `nextAllowedAt` (also\n`Retry-After`) says when to retry. Sending from a member's own mailbox is refused. The warmup gate never\nrefuses: an inbox that has not finished warming up sends, and the `201` carries a `warnings` entry\n(`warmup_not_ready`, `reason``too_young` or `unconfirmed`, `fix`, and `readyAt`\nfor `too_young`). A replay carries no warnings.\nRequires the same permission as replying in a thread (`POST /v1/threads/{threadId}/messages`), so every\nseat that can reply, Client included, can start one. The send is recorded only after the provider accepts it.\n\nNeeds the `agent_send` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "threads.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateThreadRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateThreadRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateThreadRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "agent_send"
        ]
      },
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "List threads in the current workspace.",
        "description": "Requires `ReadAccess`. `channel` is `email`, `linkedin`, or `all`.\n`limit` defaults to 50 and maxes at 100, matching the inbox list.\n`status` and `folder` are the inbox tab filters (to_reply, other,\nautomated_reply, not_interested, sent) and are applied before paging.\nEach thread is one row, its newest message in the tab, and `pagination.total` counts threads, as\n`GET /v1/threads/counts` does (DEV-4083).\nWith `q`, `pagination.total` counts at most 1,000 threads: past 1,000 it is 1,000 and\n`pagination.isTotalCapped` is true, and paging goes on while `hasMore` is true. Without `q`, or\nat 1,000 matches or fewer, the total is exact and `isTotalCapped` is omitted (DEV-4517).\nTo Reply is attributed Interested, Objection, and Wrong Contact, plus due reminders. A thread leaves it once our\nreply is its newest message, as a LinkedIn conversation does, and comes back with the lead's next reply.\n`source` is the lane on top of the tab: `accounts` (account touch threads) or `campaigns`\n(campaign threads), with the predicates of `accountsCount` and `campaignsCount` on\n`GET /v1/threads/counts`. Omitted lists every thread of the tab. A row of an account touch's thread\ncarries `accountId` and `accountName` while the accounts feature is on for the caller, and an email one\n`replyTouchId`, the account's open reply touch answering the thread, when there is one (DEV-2537). Every row\ncarries `hasDraft`, and `draftAuthor` (`user` or `agent`) when a reply draft is saved on it.\n`sort=oldest_waiting` lists the thread that has waited longest first, across pages: by `waitingSince`,\nelse by the newest message; omitted keeps the inbox order, newest first. Each row whose newest message is the\ncontact's carries `waitingSince`, when that message arrived, on any tab; it is a wait on a reply only on\n`to_reply`. A thread we answered whose reminder came due waits since that reminder (DEV-5202).",
        "operationId": "threads.list",
        "parameters": [
          {
            "name": "Channel",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "InboxId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "ContactId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Interest",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "description": "Inbox tab token: to_reply, other, automated_reply, not_interested, human_reply.\nApplied in the list query before paging. Same tokens as GET /v1/inbox/replies.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Folder",
            "in": "query",
            "description": "Inbox folder: inbox, sent, or all. Omitted means inbound, matching the legacy list.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Source",
            "in": "query",
            "description": "The inbox lane on top of the tab: accounts or campaigns, matching accountsCount and campaignsCount\nof GET /v1/threads/counts. Omitted means every thread of the tab. Any other value is 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Sort",
            "in": "query",
            "description": "`oldest_waiting`: the thread that has waited longest first, across pages, by each row's `waitingSince`,\n            else its newest message (DEV-5202). Omitted keeps the inbox order, newest first. Any other value is 400.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "IsRead",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IsArchived",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "IsSaved",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "HasReminder",
            "in": "query",
            "schema": {
              "type": "boolean"
            }
          },
          {
            "name": "TagIds",
            "in": "query",
            "schema": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int64"
              }
            }
          },
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfThreadModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfThreadModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfThreadModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads/{threadId}": {
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "Return one thread.",
        "description": "A malformed id, unknown channel, or cross-workspace thread is `not_found`. `accountId` and\n`accountName` are the account whose touch the thread is, else the account on which the thread's contact\nis a stakeholder, when there is one. An email thread that is an account touch's thread also carries\n`replyTouchId`: that account's open reply touch answering the thread, which sends the reply when approved\n(DEV-2537). `hasDraft` says a reply draft is saved on the thread and `draftAuthor` who wrote it.\nRequires `ReadAccess`.\nAn email thread carries `scheduledMessages`: replies and forwards queued on it that have not sent yet,\nincluding a teammate's reply waiting on a client seat (`awaiting_approval`, DEV-2043), which the writer\ncan withdraw with `POST /v1/scheduled-messages/{id}/cancel`.",
        "operationId": "threads.get",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "threads"
        ],
        "summary": "Update thread fields. Absent fields stay unchanged. Null `reminderAt` clears a reminder.",
        "description": "Requires `InboxReplyAccess`, matching inbox triage. The thread comes back with `hasDraft` and\n`draftAuthor`, as threads.get serves them; `accountId`, `replyTouchId` and\n`scheduledMessages` are left out (DEV-2537).",
        "operationId": "threads.update",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads/bulk-update": {
      "post": {
        "tags": [
          "threads"
        ],
        "summary": "Apply the same field update to up to 1,000 threads.",
        "description": "Returns per-id outcomes. Requires `InboxReplyAccess`.",
        "operationId": "threads.bulk-update",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadBulkResult"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadBulkResult"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadBulkResult"
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads/{threadId}/messages": {
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "List messages in a thread, oldest first.",
        "operationId": "threads.list-messages",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfThreadMessageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfThreadMessageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfThreadMessageModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "threads"
        ],
        "summary": "Send a message on a thread.",
        "description": "Email requires `senderEmailId`. An email reply goes to the thread's sender unless it names `to`, or\n`replyAll: true` (the sender, To and Cc, less the sending inbox); `cc` and `bcc` add recipients,\neach one bare email address. `attachmentIds` are `att_` ids uploaded against this thread (its newest\nmessage), and `contentType` is `html` (default) or `text`. Those six fields are email only: a\nLinkedIn reply that names any of them is `400 validation_failed` on that field and sends nothing\n(DEV-2537). LinkedIn sends plain text through the conversation seat. A LinkedIn\n`Idempotency-Key` is bound to its thread and message: reusing it on another thread, or with another\nbody once decided, returns `409 idempotency_key_reused` and sends nothing. Without a key, the same text\nrepeated in a thread more than 5 minutes later is sent again.\nAn email `Idempotency-Key` (optional, at most 200 characters, unique in the workspace) is bound to its\nthread, inbox and body, and to its `to`, `cc`, `bcc`, `replyAll`, `contentType` and\n`attachmentIds` when it names any: a retry returns the reply it scheduled, or the `202` with the client approval item\nit was held as, and queues nothing; another request under it is\n`409 idempotency_key_reused`; one still being queued is `409 in_progress` with `nextAllowedAt`\nand `Retry-After`; one Kenso cannot tell was queued is `409 outcome_unknown` and never queues again.\nA refused reply frees its key (DEV-3672).\nRequires `InboxReplyAccess`. The send is recorded only after the provider accepts it.\nAn email reply to a do-not-contact, blocklisted or unsubscribed contact returns `409 invalid_state`\nwith a `confirmSuppressed` detail whose code is the reason, and is sent only when the request repeats\nwith `confirmSuppressed: true`. LinkedIn replies to a\nsuppressed contact are always refused. An email reply is recorded with its caller: a person, an API key, or an\nagent (any credential sent with `X-Ken-Actor: agent`). An API key or agent reply from its own member's\nmailbox is not sent: it returns `202` with the scheduled message in `status: awaiting_approval` and\n`approverMemberId`, and waits in that member's `GET /v1/approvals` until they approve it in person\n(DEV-6060); with `accounts` off, or from another member's own mailbox, it is `403 forbidden`. Its reply\nfrom an inbox a member\npaused or Ken blocked from sending is a\n`409 invalid_state` whose detail code is `inbox_paused` or `inbox_send_blocked`, with a\n`fix` (DEV-3672). A block carries `nextAllowedAt` (its end) and `Retry-After`; a pause has no\nknown end and carries neither. A pause or block that starts during the undo window refuses the queued reply at\nsend time: the scheduled message ends `failed`.\nWhen the workspace requires external approval for replies,\nan email reply is not sent: the response is `202` with `status``held_for_client_approval` and the `clientApprovalItemId` that holds it (DEV-1526). An email reply a\nteammate writes in person from a client seat's own inbox, with `accounts_send` on, is not sent either: it\nreturns `202` with the scheduled message (`ScheduledMessageModel`) in `status: awaiting_approval`\nand `approverMemberId`, and waits in that client's `GET /v1/approvals` (DEV-2043). Email\n`archiveAfterSend: true` archives the thread once the reply sends; a waiting reply archives only when the\napproved reply sends, never while it waits.\nAn API key or agent LinkedIn reply through a seat another member connected is not sent (DEV-6464): it returns\n`202` with `status: awaiting_approval`, `channel: linkedin`, the `approvalId` (type\n`reply.linkedin`) and `approverMemberId` (the seat owner), and waits in that member's\n`GET /v1/approvals` until they approve it in person, when it sends once. A retry with the same\n`Idempotency-Key` (or the same text without one) returns the same waiting reply. With `accounts` off for\nthe owner, or a seat no member connected, it is `403 forbidden`. A person's own reply from the dashboard, and\nthe seat owner's own agent or API key, send as before.",
        "operationId": "threads.create-message",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateThreadMessageRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateThreadMessageRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateThreadMessageRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageModel"
                }
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageHeldModel"
                    },
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                    },
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageAwaitingApprovalModel"
                    }
                  ]
                }
              },
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageHeldModel"
                    },
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                    },
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageAwaitingApprovalModel"
                    }
                  ]
                }
              },
              "text/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageHeldModel"
                    },
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                    },
                    {
                      "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadMessageAwaitingApprovalModel"
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads/{threadId}/forward": {
      "post": {
        "tags": [
          "threads"
        ],
        "summary": "Forward an email thread to new recipients.",
        "description": "Requires `MemberReadAccess` (a white-label Client replies but does not forward). Email only. The forward is queued and the provider\nconfirms delivery later. `to` is required unless `replyAll` is true.\n`delaySeconds` is 60 or 300. `attachmentIds` are `att_` ids for this thread.\nEvery recipient is one bare email address. A forward that reaches the thread (`replyAll` without\n`to`, or the contact or another participant as a recipient) returns `409 invalid_state` when the\ncontact is suppressed (detail code is the reason; there is no confirm override, send a reply instead) or\nwhen the workspace holds replies for external approval (detail code `client_approval_required`).\nA queued forward returns `200` with the scheduled message. An API key or agent forward from its own\nmember's mailbox is not sent: it returns `202` with the scheduled message in\n`status: awaiting_approval` and `approverMemberId`, and waits in that member's\n`GET /v1/approvals` until they approve it in person (DEV-6060); with `accounts` off, or from another\nmember's own mailbox, it is `403 forbidden`.",
        "operationId": "threads.forward",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ForwardThreadRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/ForwardThreadRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/ForwardThreadRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              }
            }
          },
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfScheduledMessageModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/threads/{threadId}/draft": {
      "get": {
        "tags": [
          "threads"
        ],
        "summary": "Return the saved draft for a thread.",
        "description": "`authorSource` says who last wrote it: `user`, a person in the dashboard, or `agent` (DEV-2537).\n            The agent's draft also carries `mirror`, the same reply in the reader's language, when it wrote in the lead's\n            (DEV-1708); otherwise it is absent.",
        "operationId": "threads.get-draft",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadDraftModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadDraftModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadDraftModel"
                }
              }
            }
          }
        }
      },
      "put": {
        "tags": [
          "threads"
        ],
        "summary": "Replace the draft for a thread. An empty body deletes it.",
        "description": "Only a person in a dashboard session writes as the draft's author. An agent (`X-Ken-Actor: agent`), an\nMCP token or an API key writes as agent: it never overwrites or empty-deletes a person's draft, and the\nresponse is the person's draft unchanged (DEV-3111).",
        "operationId": "threads.replace-draft",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertThreadDraftRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertThreadDraftRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpsertThreadDraftRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadDraftModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadDraftModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfThreadDraftModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "threads"
        ],
        "summary": "Delete the draft for a thread.",
        "operationId": "threads.delete-draft",
        "parameters": [
          {
            "name": "threadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/campaigns/{campaignId}/tracking-links": {
      "get": {
        "tags": [
          "tracking-links"
        ],
        "summary": "List a campaign's tracking links in the current workspace.",
        "description": "Ordered by id. Read-only. Requires `ReadAccess`.",
        "operationId": "tracking-links.list",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTrackingLinkModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTrackingLinkModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTrackingLinkModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "tracking-links"
        ],
        "summary": "Create a tracking link on a campaign in the current workspace.",
        "description": "Returns `201` and `Location`. Requires `WriteAccess`.",
        "operationId": "tracking-links.create",
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTrackingLinkRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTrackingLinkRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTrackingLinkRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tracking-links/{trackingLinkId}": {
      "get": {
        "tags": [
          "tracking-links"
        ],
        "summary": "Return one tracking link in the current workspace.",
        "description": "A missing or cross-workspace id is `not_found`. Requires `ReadAccess`.",
        "operationId": "tracking-links.get",
        "parameters": [
          {
            "name": "trackingLinkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "tracking-links"
        ],
        "summary": "Update a tracking link.",
        "description": "Absent fields stay unchanged. JSON null clears `textValue`. Requires `WriteAccess`. A new\n`domainName` goes through the URL reputation check, and changing it after mail with the link went out\ncounts against a daily cap (`429 rate_limited` with `Retry-After` once `UrlReputation:Mode` is\n`Enforce`). A new `domainName` on a link served from a Kenso shared tracking host is\n`409 shared_host_link_frozen`, and off a paid plan `402 plan_limit_reached` (`refusal.code``link_edit_requires_paid_plan`), when `Redirects:LinkEdits:Mode` is Enforce (DEV-3690).",
        "operationId": "tracking-links.update",
        "parameters": [
          {
            "name": "trackingLinkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTrackingLinkRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTrackingLinkRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateTrackingLinkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTrackingLinkModel"
                }
              }
            }
          },
          "402": {
            "description": "Payment Required",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "409": {
            "description": "Conflict",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "tracking-links"
        ],
        "summary": "Soft-delete a tracking link and deactivate the links generated from it.",
        "description": "Requires Delivery edit access (owners, admins and editors by default). Returns `204`.",
        "operationId": "tracking-links.delete",
        "parameters": [
          {
            "name": "trackingLinkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/translations": {
      "post": {
        "tags": [
          "translations"
        ],
        "summary": "Translate plain text into one language.",
        "description": "`text` (required, at most 8,000 characters) is plain text; the result keeps its line breaks, names, links,\n            numbers and `{placeholders}`. `targetLanguage` is a two-letter ISO 639-1 code, such as `en`.\n            `messageId` is optional: an email `msg_` id of the workspace caches the result on that message, so the\n            next call for the same language answers from it with no model call; another workspace's email is 404; a LinkedIn\n            `msg_` id is accepted and not cached. Answers `{ text, sourceLanguage }`, where `sourceLanguage` is\n            the input's ISO 639-1 code or `und`. A failed model call is 503 \"Couldn't translate\". Requires inbox view\n            and Ask. Each call takes one unit of the workspace's `aiTranslations` quota (20 a minute, 500 a day):\n            past it, 429 `quota_exceeded` with `Retry-After`.\n\nNeeds the `multilingual_outreach` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "translations.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTranslationRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTranslationRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTranslationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTranslationModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTranslationModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTranslationModel"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "404": {
            "description": "Not Found",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProblemDetails"
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalFailure"
                }
              }
            }
          },
          "503": {
            "description": "Service Unavailable"
          }
        },
        "x-ken-features": [
          "multilingual_outreach"
        ]
      }
    },
    "/v1/trigger-firings": {
      "get": {
        "tags": [
          "trigger-firings"
        ],
        "summary": "List trigger firings in the current workspace.",
        "operationId": "trigger-firings.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "TriggerId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerFiringModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerFiringModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerFiringModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/trigger-schemas": {
      "get": {
        "tags": [
          "trigger-schemas"
        ],
        "summary": "Parameter schemas for each signal type.",
        "operationId": "trigger-schemas.list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerSchemaModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerSchemaModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerSchemaModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/triggers/preview": {
      "post": {
        "tags": [
          "triggers"
        ],
        "summary": "Preview the companies a trigger would act on, with pass counts per gate step and an estimated credit cost.",
        "description": "Runs the definition's parameters against live data without saving anything: nothing fires and nothing is\ncharged. `signalType` is `fundraising`, `open_roles` or `company_headcount_growth`; any other\nsignal returns 400 `validation_failed` with `details[0].code``preview_not_supported`.\n`parameters` is a JSON object with the same keys a trigger stores. `limit` 1 to 25 companies (default\n25), cursor pagination through `pagination.nextCursor`. Every page has `companies` (sample rows),\n`total` (the source's count across pages, null for `open_roles`), `steps` (name, count and\ndescription of each gate step on this page, in order, ending with `max_contacts_per_company`, the most people\nthe page can import) and `estimatedCredits` (`isEstimate` true, `leads`, `credits`,\n`totalMillicredits`, `lines`, and `basis`, which says how it was computed: those people at the\nleads rate of `credit-estimates.create`). Free: never uses the export allowance.",
        "operationId": "triggers.preview",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewTriggerRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewTriggerRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PreviewTriggerRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfJsonElement"
                }
              }
            }
          }
        }
      }
    },
    "/v1/triggers/{triggerId}/test-fire": {
      "post": {
        "tags": [
          "triggers"
        ],
        "summary": "Test-fire a saved trigger against a sample signal.",
        "description": "Evaluates one sample signal of the trigger's own type, the way an arriving signal is evaluated, and says whether it\nwould fire and why. Read-only: no signal is queued, no cooldown is taken, no firing is written, no window counter\nchanges, and nothing is sent or charged. Recent signals are not replayed; the sample is the only input.\n`contactId` is required, `campaignId` feeds the audience filter, `payload` is the signal's JSON\nobject (for example `clickedUrl` for `link_clicked`, `classification` for `reply_received`),\n`occurredAt` defaults to now. `checks` run in pipeline order (`status`, `audience_filter`,\n`parameters`, `cooldown`), every one runs, and `rejectedBy` names the first that failed;\n`status` fails for a paused or archived trigger and for one whose campaign is deleted. A firing\ncan still be suppressed later (do not contact, blocklist, frequency cap). A contact or campaign outside the\nworkspace is 400; signals that only a scheduled sweep produces return 400 with `details[0].code``test_fire_not_supported`.",
        "operationId": "triggers.test-fire",
        "parameters": [
          {
            "name": "triggerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TestFireTriggerRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/TestFireTriggerRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/TestFireTriggerRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerTestFireModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerTestFireModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerTestFireModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/triggers": {
      "get": {
        "tags": [
          "triggers"
        ],
        "summary": "List trigger definitions in the current workspace.",
        "operationId": "triggers.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "CampaignId",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfTriggerModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "triggers"
        ],
        "summary": "Create a trigger definition.",
        "description": "Requires Campaigns edit access (owners, admins and editors by default). The campaign must belong to the workspace and be in trigger mode, or be a Batch campaign when `switchCampaignToTrigger` is true (the switch and the create are one transaction); the LinkedIn signal types (`linkedin_post_engagement`, `linkedin_profile_view`) take a regular campaign instead and need the workspace's `linkedin_signals` flag.",
        "operationId": "triggers.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTriggerRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTriggerRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTriggerRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/triggers/{triggerId}": {
      "get": {
        "tags": [
          "triggers"
        ],
        "summary": "Get one trigger definition.",
        "operationId": "triggers.get",
        "parameters": [
          {
            "name": "triggerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "triggers"
        ],
        "summary": "Update a trigger definition.",
        "description": "Requires Campaigns edit access (owners, admins and editors by default). Omitted fields stay unchanged. `audienceFilter: null` clears the filter.",
        "operationId": "triggers.update",
        "parameters": [
          {
            "name": "triggerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { }
            },
            "text/json": {
              "schema": { }
            },
            "application/*+json": {
              "schema": { }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "triggers"
        ],
        "summary": "Archive a trigger definition.",
        "operationId": "triggers.delete",
        "parameters": [
          {
            "name": "triggerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/triggers/{triggerId}/stats": {
      "get": {
        "tags": [
          "triggers"
        ],
        "summary": "Firing stats for one trigger.",
        "operationId": "triggers.get-stats",
        "parameters": [
          {
            "name": "triggerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Days",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerStatsModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerStatsModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfTriggerStatsModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/triggers/{triggerId}/linkedin-engagements": {
      "get": {
        "tags": [
          "triggers"
        ],
        "summary": "LinkedIn engagements a LinkedIn signal trigger stored.",
        "description": "Newest first. `status` filters to `new`, `imported`, `offered` or `skipped`. Each item names the engager\n(`actor`), the post and comment when there is one, and for `imported` the person's contact in the\ncampaign; `skipReason` says why an item was `skipped`. Items also carry the reaction type, the comment\nand parent comment ids, the post text, Jev's intent and reason, and `ownPost`. A trigger of another signal type returns an\nempty list. 404 while the workspace's `linkedin_signals` flag is off.\n\nNeeds the `linkedin_signals` feature on your workspace. Until it is on, calls answer 404.",
        "operationId": "triggers.list-linkedin-engagements",
        "parameters": [
          {
            "name": "triggerId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "description": "Page size, 1 to 200 (default 50).",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "description": "Opaque cursor from `pagination.nextCursor`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Status",
            "in": "query",
            "description": "`new`, `imported`, `offered` or `skipped`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInEngagementModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInEngagementModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfLinkedInEngagementModel"
                }
              }
            }
          }
        },
        "x-ken-features": [
          "linkedin_signals"
        ]
      }
    },
    "/v1/webhook-endpoints": {
      "get": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "List webhook endpoints in the current workspace.",
        "description": "Each endpoint's `health`, `lastDelivery` and `failedAttempts` come from its latest 10 attempts.",
        "operationId": "webhook-endpoints.list",
        "parameters": [
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookEndpointModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookEndpointModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookEndpointModel"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Register a webhook endpoint.",
        "description": "Requires the integrations permission (admins by default). `url` must be https outside Development. `events` is a non-empty set of supported event types. `app` (`zapier`, `make` or `n8n`) tags the endpoint; omitted, it is taken from the URL host.\n`campaignIds` (workspace campaigns; another workspace's id is `not_found`) and `classifications` (snake_case labels) filter\ndeliveries; both together must both match. A filter holds at most 10 campaigns, 10 classifications, or campaigns times\nclassifications up to 10. `isBatched` delivers the high-volume types as batches; it needs an `events` list and is refused while batching is off.",
        "operationId": "webhook-endpoints.create",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookEndpointRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookEndpointRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookEndpointRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-endpoints/{webhookEndpointId}": {
      "get": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Get one webhook endpoint.",
        "description": "`health`, `lastDelivery` and `failedAttempts` come from the endpoint's latest 10 attempts.",
        "operationId": "webhook-endpoints.get",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Update a webhook endpoint.",
        "description": "Requires the integrations permission (admins by default). Omitted fields stay unchanged. `isDisabled` pauses or resumes delivery. `app` sets the app tag; an empty string clears it.\n`campaignIds` and `classifications` replace that filter (empty clears it); the one omitted keeps its value. `isBatched` turns batch delivery on or off.",
        "operationId": "webhook-endpoints.update",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookEndpointRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookEndpointRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateWebhookEndpointRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointModel"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Delete a webhook endpoint.",
        "operationId": "webhook-endpoints.delete",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          }
        }
      }
    },
    "/v1/webhook-endpoints/{webhookEndpointId}/signing-secret": {
      "get": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Get the endpoint signing secret.",
        "description": "Requires the integrations permission (admins by default). Treat `secret` as a credential.",
        "operationId": "webhook-endpoints.get-signing-secret",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookSigningSecretModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookSigningSecretModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookSigningSecretModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-endpoints/{webhookEndpointId}/deliveries": {
      "get": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "List delivery attempts for one endpoint.",
        "description": "`cursor` is the provider cursor from the previous page. `limit` is 1 to 200.",
        "operationId": "webhook-deliveries.list",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookDeliveryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookDeliveryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookDeliveryModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-endpoints/{webhookEndpointId}/deliveries/{deliveryId}/resend": {
      "post": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Replay one delivery to this endpoint.",
        "description": "`deliveryId` is a delivery's `id` (`atmpt_...`) or its `messageId` (`msg_...`) from the\n            deliveries list. An `id` is looked up among this endpoint's newest 1,000 deliveries; an older or unknown\n            one is `not_found`, so resend an older delivery by its `messageId`. The response echoes the id sent.",
        "operationId": "webhook-deliveries.resend",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deliveryId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookDeliveryResendModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookDeliveryResendModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookDeliveryResendModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-endpoints/{webhookEndpointId}/recover": {
      "post": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Resend failed deliveries since a time.",
        "description": "Resends every delivery to this endpoint that failed in the window and never succeeded. `since` is required and at\nmost 14 days ago; `until` defaults to now. Svix runs the resends in the background, so the response is\n`202` with the window. Counts as 10 resends against the workspace's resend limit.",
        "operationId": "webhook-endpoints.recover",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RecoverWebhookDeliveriesRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/RecoverWebhookDeliveriesRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/RecoverWebhookDeliveriesRequest"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookRecoverModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookRecoverModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookRecoverModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-endpoints/{webhookEndpointId}/test": {
      "post": {
        "tags": [
          "webhook-endpoints"
        ],
        "summary": "Send a test event to one endpoint.",
        "description": "Requires the `integrations` feature. Sends the example payload of `eventType` to this endpoint only and\nwaits up to 5 seconds for the first attempt. `eventType` is any event type available to the workspace, whether or\nnot the endpoint receives it or filters by campaign or classification; it defaults to the first event the endpoint\nreceives (`reply.received` when it receives every event). A batched endpoint gets a high-volume type's\n`<type>.batch` example, and `eventType` in the response says so. A type the workspace cannot use is\n`validation_failed`. A disabled endpoint is `invalid_state`.",
        "operationId": "webhook-endpoints.test",
        "parameters": [
          {
            "name": "webhookEndpointId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendWebhookEndpointTestRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/SendWebhookEndpointTestRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/SendWebhookEndpointTestRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointTestModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointTestModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWebhookEndpointTestModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/webhook-event-types": {
      "get": {
        "tags": [
          "webhook-event-types"
        ],
        "summary": "List the webhook event types this workspace can subscribe to.",
        "description": "The event catalog, in display order: each type's group, description, the delivery filters it supports\n(`campaign`, `classification`, `channel`), whether it is offered as an MCP event, whether it is\nhigh-volume, and a sample body. Types still rolling out are listed only for workspaces they are enabled for.",
        "operationId": "webhook-event-types.list",
        "parameters": [
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          },
          {
            "name": "X-Ken-Workspace-Id",
            "in": "header",
            "description": "Workspace to act in. Required when your credential can reach more than one workspace (otherwise `400 workspace_required`).",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookEventTypeModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookEventTypeModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWebhookEventTypeModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces": {
      "get": {
        "tags": [
          "workspaces"
        ],
        "summary": "List the caller's workspaces.",
        "description": "Replaces `GET /v1/workspaces/me`, `GET /v1/workspaces/search`, and\n`GET /v1/clients` for the caller's own memberships. Ordered by id.\n`q` matches the workspace name. Requires `ReadAccess`.",
        "operationId": "workspaces.list",
        "parameters": [
          {
            "name": "Q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "format": "int32"
            }
          },
          {
            "name": "Cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWorkspaceSummaryModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWorkspaceSummaryModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalListResponseOfWorkspaceSummaryModel"
                }
              }
            }
          }
        }
      }
    },
    "/v1/workspaces/{workspaceId}": {
      "get": {
        "tags": [
          "workspaces"
        ],
        "summary": "Return one workspace.",
        "description": "Replaces `GET /v1/clients/{id}` and `GET /v1/workspaces/{id}/company`.\nNon-members receive 403. Requires `ReadAccess`.",
        "operationId": "workspaces.get",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkspaceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkspaceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkspaceModel"
                }
              }
            }
          }
        }
      },
      "patch": {
        "tags": [
          "workspaces"
        ],
        "summary": "Update a workspace.",
        "description": "Absent fields stay unchanged. Null clears a string field, except `name`: a workspace keeps a name of\n1 to 50 characters. Requires a workspace admin.\nThe benchmark and target (DEV-5223): `replyRateBenchmark`, `replyRateTarget`,\n`positiveReplyRateBenchmark` and `positiveReplyRateTarget` in percent from 0 to 100 (replies and\ninterested replies per person contacted, as analytics computes them, not the share of replies),\n`meetingsPerMonthBenchmark` and `meetingsPerMonthTarget` from 0 to 10000. Two decimals are kept, and\nnull clears one. Out of range is 400 `validation_failed` on that field.",
        "operationId": "workspaces.update",
        "parameters": [
          {
            "name": "workspaceId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          },
          {
            "name": "Ken-Version",
            "in": "header",
            "description": "The API version: a dated version (YYYY-MM-DD), or 1.1, another name for the first dated version. Without it the request uses your API key's pinned version; an unpinned key reaches the legacy shape of the same path. 1.0 selects the legacy shape explicitly.",
            "required": true,
            "schema": {
              "enum": [
                "2026-11-02",
                "1.1"
              ],
              "type": "string",
              "default": "2026-11-02"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchWorkspaceRequest"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/PatchWorkspaceRequest"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/PatchWorkspaceRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkspaceModel"
                }
              },
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkspaceModel"
                }
              },
              "text/json": {
                "schema": {
                  "$ref": "#/components/schemas/CanonicalResourceResponseOfWorkspaceModel"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "AccessRequestModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "description": "page, feature, or credits.",
            "nullable": true
          },
          "key": {
            "type": "string",
            "description": "A page or feature wire name; monthly_limit for credits.",
            "nullable": true
          },
          "level": {
            "type": "string",
            "description": "view or edit. Page requests only.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "pending, granted, declined, or canceled.",
            "nullable": true
          },
          "requesterId": {
            "type": "integer",
            "description": "The member who asked (a member id is a user id).",
            "format": "int64"
          },
          "decidedById": {
            "type": "integer",
            "description": "Who granted, declined or canceled it. Omitted while pending.",
            "format": "int64",
            "nullable": true
          },
          "decidedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A member's request for a page, a feature or credits (DEV-1654)."
      },
      "AcknowledgeComplianceRequest": {
        "type": "object",
        "properties": {
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ISO-2 codes of countries the compliance read lists, such as `ES` (any casing).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of POST /v1/campaigns/{campaignId}/compliance/acknowledgements."
      },
      "ActorModel": {
        "required": [
          "kind"
        ],
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "memberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AgentActionModel": {
        "type": "object",
        "properties": {
          "actionId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "description": "`applied`, `undone`, `undo_failed` or `failed`.",
            "nullable": true
          },
          "undoneAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "keptLeads": {
            "type": "integer",
            "description": "A top-up only: the leads it added that the undo kept because the sequencer had started them. Omitted for any other\nkind.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "An agent action after an undo (DEV-3671)."
      },
      "AgentActionOutcomeModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`applied`, `proposed` (a person decides it in Approvals) or `refused`.",
            "nullable": true
          },
          "actionId": {
            "type": "integer",
            "description": "The applied action; undo it with `POST /v1/agent-team/actions/{actionId}/undo`. Applied only.",
            "format": "int64",
            "nullable": true
          },
          "undoUntil": {
            "type": "string",
            "description": "Until when the action can be undone; omitted when the kind has no undo. Applied only.",
            "format": "date-time",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "description": "What changed, in a sentence. Applied only.",
            "nullable": true
          },
          "approvalId": {
            "type": "string",
            "description": "The proposal, `request_<id>`, as `/v1/approvals` lists it. Proposed only.",
            "nullable": true
          },
          "why": {
            "type": "string",
            "description": "Why a person has to decide (Autopilot off, a standing rule, outside the bounds). Proposed only.",
            "nullable": true
          },
          "code": {
            "type": "string",
            "description": "`unknown_kind`, `kind_not_allowed`, `invalid_args`, `campaign_not_found`, `campaign_paused`,\n            `workspace_suspended`, `apply_failed`, `needs_a_user`, `already_undone` (the key's action was\n            undone: send a new key) or `busy` (another change to the campaign is being checked: retry). Refused only.",
            "nullable": true
          },
          "message": {
            "type": "string",
            "description": "Why it was refused, for a person. Refused only.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What became of a requested agent action (DEV-3671): one shape whether it was applied, turned into a proposal or\nrefused, so an agent reads one answer."
      },
      "AgentProposalModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "`request_<id>`, the id `/v1/approvals` lists it under.",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`pending`, `awaiting_client`, `applied`, `rejected`, `expired`, `superseded` or\n            `failed`, as it reads now.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "Omitted for a workspace-level proposal.",
            "format": "int64",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "args": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonNode"
            },
            "description": "The arguments that apply on approval.",
            "nullable": true
          },
          "urgent": {
            "type": "boolean"
          },
          "requiresClientYes": {
            "type": "boolean",
            "description": "A schedule or volume change on a client workspace: approving needs the client's yes."
          },
          "requestedBy": {
            "$ref": "#/components/schemas/AgentRequesterModel"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "decidedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decidedBy": {
            "$ref": "#/components/schemas/AgentTeamPersonModel"
          },
          "error": {
            "type": "string",
            "description": "Why it was skipped or failed to apply.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A proposal a person decides in Approvals (DEV-3671)."
      },
      "AgentRequesterModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Who asked: `kind``agent`, `user` or `api_key`, and the label the card shows."
      },
      "AgentStandingRuleSummaryModel": {
        "type": "object",
        "properties": {
          "ruleId": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "description": "Omitted for a workspace-wide rule.",
            "format": "int64",
            "nullable": true
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "author": {
            "$ref": "#/components/schemas/AgentTeamPersonModel"
          }
        },
        "additionalProperties": false,
        "description": "A standing rule in force."
      },
      "AgentTeamChangeModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "kind": {
            "type": "string",
            "description": "`version_added`, `version_removed`, `version_paused`, `copy_edited`, `ai_prompt_changed`,\n            `schedule_changed`, `volume_changed`, `inbox_added`, `inbox_removed`, `list_imported`,\n            `contacts_removed`, `segment_changed`, `status_changed`, `duplicated_from`,\n            `linked_in_step_changed`, `default_made` or `default_undone`.",
            "nullable": true
          },
          "actor": {
            "$ref": "#/components/schemas/AgentRequesterModel"
          },
          "requestId": {
            "type": "string",
            "description": "`aact_<id>` for an agent action, `request_<id>` for an approved proposal.",
            "nullable": true
          },
          "diff": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonNode"
            },
            "description": "What changed, before and after, when the kind records it.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One row of the campaign change log."
      },
      "AgentTeamChangedActionModel": {
        "type": "object",
        "properties": {
          "actionId": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "description": "`applied`, `undone`, `undo_failed` or `failed`.",
            "nullable": true
          },
          "appliedAt": {
            "type": "string",
            "format": "date-time"
          },
          "undoUntil": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "actorLabel": {
            "type": "string",
            "nullable": true
          },
          "authority": {
            "type": "string",
            "description": "`autopilot` (inside the bounds) or `approval` (a person approved it).",
            "nullable": true
          },
          "keptLeads": {
            "type": "integer",
            "description": "An undone top-up only: the leads the undo kept because the sequencer had started them.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "An agent action applied in the window."
      },
      "AgentTeamChangesModel": {
        "type": "object",
        "properties": {
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "until": {
            "type": "string",
            "format": "date-time"
          },
          "truncated": {
            "type": "boolean",
            "description": "More than 200 changes: only the newest 200 are listed."
          },
          "changes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentTeamChangeModel"
            },
            "nullable": true
          },
          "actions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentTeamChangedActionModel"
            },
            "nullable": true
          },
          "proposals": {
            "$ref": "#/components/schemas/AgentTeamProposalsModel"
          },
          "standingRules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentStandingRuleSummaryModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What changed on the workspace's campaigns between `since` and `until` (DEV-3671)."
      },
      "AgentTeamPersonModel": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A member: the id, and the name when the member still exists (DEV-3671)."
      },
      "AgentTeamProposalsModel": {
        "type": "object",
        "properties": {
          "open": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentProposalModel"
            },
            "description": "Pending or awaiting the client now.",
            "nullable": true
          },
          "decided": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentProposalModel"
            },
            "description": "Applied, rejected, expired, superseded or failed in the window.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AiLineHoldApprovalModel": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "integer",
            "description": "The released contact.",
            "format": "int64"
          },
          "restoredLineCount": {
            "type": "integer",
            "description": "The held lines that became the contact's live lines.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "An approved hold."
      },
      "AiLineHoldLineModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "The AI line id.",
            "format": "int64"
          },
          "promptId": {
            "type": "integer",
            "description": "The prompt that wrote the line.",
            "format": "int64"
          },
          "variable": {
            "type": "string",
            "description": "The template variable the line fills, the prompt's name (for example `first_line`).",
            "nullable": true
          },
          "text": {
            "type": "string",
            "description": "The line's text.",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "description": "The segment the line was written for. Omitted when the line is not segment-scoped.",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "description": "The sequence step the line was written for. Omitted when the line serves every step.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One line a hold keeps."
      },
      "AiLineHoldModel": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "integer",
            "description": "The held contact.",
            "format": "int64"
          },
          "reasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Why the lines were held, the first the main reason: `ungrounded` (a fact the lead's data does not support),\n`not_specific`, `tone` (a phrase a person would not say), or `too_long`. Clients tolerate new values.",
            "nullable": true
          },
          "heldAt": {
            "type": "string",
            "description": "When the contact was held.",
            "format": "date-time"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiLineHoldLineModel"
            },
            "description": "The lines the hold keeps for review. Approving makes them the lines the contact sends.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A contact the AI line check held: its lines failed the check and the rewrite failed it too (DEV-918)."
      },
      "AiRunDryRunModel": {
        "type": "object",
        "properties": {
          "dryRun": {
            "type": "boolean"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "flow": {
            "type": "string",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "processAll": {
            "type": "boolean"
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "batchSize": {
            "type": "integer",
            "description": "Contacts one run submits: the requested batch, else the flow's limit (process all) or 500.",
            "format": "int32"
          },
          "eligibleCount": {
            "type": "integer",
            "description": "Contacts eligible for the flow now, in the segment when one is set.",
            "format": "int32"
          },
          "projectedContactCount": {
            "type": "integer",
            "description": "The lower of `eligibleCount` and `batchSize`: an upper bound on what the run processes.",
            "format": "int32"
          },
          "blockingGate": {
            "type": "string",
            "nullable": true
          },
          "blockingReason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What `ai-runs.create` with `dryRun` would process. Nothing is queued."
      },
      "AiRunEligibilityModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "flows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiRunFlowEligibilityModel"
            },
            "nullable": true
          },
          "preview": {
            "$ref": "#/components/schemas/AiRunInvalidationPreviewModel"
          }
        },
        "additionalProperties": false
      },
      "AiRunFlowEligibilityModel": {
        "type": "object",
        "properties": {
          "flow": {
            "type": "string",
            "nullable": true
          },
          "eligibleCount": {
            "type": "integer",
            "format": "int32"
          },
          "blockingGate": {
            "type": "string",
            "nullable": true
          },
          "blockingReason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AiRunInvalidationImpactModel": {
        "type": "object",
        "properties": {
          "qualificationResponses": {
            "type": "integer",
            "format": "int32"
          },
          "qualifiedFlags": {
            "type": "integer",
            "format": "int32"
          },
          "segmentationReasoning": {
            "type": "integer",
            "format": "int32"
          },
          "segmentationAssignmentsKept": {
            "type": "integer",
            "format": "int32"
          },
          "segmentationAssignmentsReset": {
            "type": "integer",
            "format": "int32"
          },
          "personalizationLines": {
            "type": "integer",
            "format": "int32"
          },
          "personalizationLeads": {
            "type": "integer",
            "format": "int32"
          },
          "rewritingLines": {
            "type": "integer",
            "format": "int32"
          },
          "rewritingLeads": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "AiRunInvalidationPreviewModel": {
        "type": "object",
        "properties": {
          "flow": {
            "type": "string",
            "nullable": true
          },
          "preview": {
            "type": "string",
            "nullable": true
          },
          "hasImpact": {
            "type": "boolean"
          },
          "cascadeFlows": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "campaignStatus": {
            "type": "string",
            "nullable": true
          },
          "sendingStatus": {
            "type": "string",
            "nullable": true
          },
          "emailsSent": {
            "type": "integer",
            "format": "int32"
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "impact": {
            "$ref": "#/components/schemas/AiRunInvalidationImpactModel"
          }
        },
        "additionalProperties": false
      },
      "AiRunModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "flow": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "contactsProcessed": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "batchId": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AiRunResetModel": {
        "type": "object",
        "properties": {
          "flows": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "batchesCancelled": {
            "type": "integer",
            "format": "int32"
          },
          "runsCancelled": {
            "type": "integer",
            "format": "int32"
          },
          "aiResponseLinesDeleted": {
            "type": "integer",
            "format": "int32"
          },
          "aiResponsesDeleted": {
            "type": "integer",
            "format": "int32"
          },
          "outreachStatusesRemoved": {
            "type": "integer",
            "format": "int32"
          },
          "qualificationResponsesDeleted": {
            "type": "integer",
            "format": "int32"
          },
          "segmentationReasoningDeleted": {
            "type": "integer",
            "format": "int32"
          },
          "contactsQualificationReset": {
            "type": "integer",
            "format": "int32"
          },
          "contactsSegmentReset": {
            "type": "integer",
            "format": "int32"
          },
          "contactsReset": {
            "type": "integer",
            "description": "Contacts a reset-contacts call cleared. Omitted on a campaign-wide reset.",
            "format": "int32",
            "nullable": true
          },
          "contactsSkipped": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiRunResetSkippedContactModel"
            },
            "description": "Named contacts a reset-contacts call left untouched. Omitted on a campaign-wide reset.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AiRunResetSkippedContactModel": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "integer",
            "format": "int64"
          },
          "reason": {
            "type": "string",
            "description": "`not_in_campaign`, `sent_or_exported`, `queued_to_send`, or `in_flight`.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AiVariableFilterDto": {
        "type": "object",
        "properties": {
          "promptId": {
            "type": "integer",
            "format": "int64"
          },
          "operator": {
            "$ref": "#/components/schemas/AiVariableFilterOperatorEnum"
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AiVariableFilterOperatorEnum": {
        "enum": [
          "Exists",
          "NotExists",
          "Contains",
          "NotContains"
        ],
        "type": "string"
      },
      "AnalyticsQueryRequest": {
        "type": "object",
        "properties": {
          "metrics": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "groupBy": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "filters": {
            "type": "object",
            "additionalProperties": { },
            "nullable": true
          },
          "window": {
            "$ref": "#/components/schemas/AnalyticsWindowInput"
          },
          "compareTo": {
            "type": "string",
            "nullable": true
          },
          "timeZone": {
            "type": "string",
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "rateBasis": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AnalyticsQueryResult": {
        "type": "object",
        "properties": {
          "window": {
            "$ref": "#/components/schemas/AnalyticsWindowModel"
          },
          "previousWindow": {
            "$ref": "#/components/schemas/AnalyticsWindowModel"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnalyticsQueryRow"
            },
            "nullable": true
          },
          "totals": {
            "$ref": "#/components/schemas/AnalyticsQueryTotals"
          },
          "truncated": {
            "type": "boolean"
          },
          "asOf": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "AnalyticsQueryRow": {
        "type": "object",
        "properties": {
          "dimensions": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "nullable": true
          },
          "labels": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "metrics": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double",
              "nullable": true
            },
            "nullable": true
          },
          "previous": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double",
              "nullable": true
            },
            "nullable": true
          },
          "sample": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "stillFilling": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AnalyticsQueryTotals": {
        "type": "object",
        "properties": {
          "metrics": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double",
              "nullable": true
            },
            "nullable": true
          },
          "previous": {
            "type": "object",
            "additionalProperties": {
              "type": "number",
              "format": "double",
              "nullable": true
            },
            "nullable": true
          },
          "sample": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "stillFilling": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AnalyticsWindowInput": {
        "type": "object",
        "properties": {
          "preset": {
            "type": "string",
            "nullable": true
          },
          "from": {
            "type": "string",
            "format": "date",
            "nullable": true
          },
          "to": {
            "type": "string",
            "format": "date",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AnalyticsWindowModel": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date"
          },
          "to": {
            "type": "string",
            "format": "date"
          },
          "timeZone": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AttachmentModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "messageId": {
            "type": "string",
            "nullable": true
          },
          "fileName": {
            "type": "string",
            "nullable": true
          },
          "contentType": {
            "type": "string",
            "nullable": true
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "AutoPauseModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Opaque id, stable for one pause.",
            "nullable": true
          },
          "scope": {
            "type": "string",
            "description": "`inbox`, `domain`, `campaign` or `workspace`. A domain pause blocks its inboxes, not\n            campaigns. A workspace pause (reason `workspace_breaker`) blocks every inbox of the workspace until\n            Kenso support releases it.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Snake_case reason code: `mailbox_hard_bounce_rate`, `campaign_hard_bounce_rate`,\n`domain_complaint_rate`, `domain_gmail_spam_rate`, `domain_placement_spam`,\n`reply_ingest_dead`, `uri_blocklist_listed`, `domain_dns_unresolvable`,\n`tenant_ban`, `mailbox_sender_ndr_rate`, `workspace_breaker` or `send_failures`.\nNew codes may be added.",
            "nullable": true
          },
          "metric": {
            "type": "string",
            "description": "`bounce_rate`, `complaint_rate`, `gmail_spam_rate`, `sender_ndr_rate` (own-tenant\n            sender-block NDRs over sends) or `dns`; `other` only for a reason added later. Omitted when no rate drives the reason (`tenant_ban`, `reply_ingest_dead`,\n            `uri_blocklist_listed`, `domain_placement_spam`, `workspace_breaker`, `send_failures`).",
            "nullable": true
          },
          "rate": {
            "type": "number",
            "description": "The rate that tripped the pause, a fraction from 0 to 1. Omitted when the signal has none.",
            "format": "double",
            "nullable": true
          },
          "threshold": {
            "type": "number",
            "description": "The threshold the rate crossed, a fraction from 0 to 1. Omitted when the signal has none.",
            "format": "double",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "inboxEmail": {
            "type": "string",
            "nullable": true
          },
          "inboxCount": {
            "type": "integer",
            "description": "Inboxes the pause blocked. Omitted for a campaign.",
            "format": "int32",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "description": "When the pause started. A renewal of a block still in force is the same pause.",
            "format": "date-time"
          },
          "blockedUntil": {
            "type": "string",
            "description": "When an inbox, domain or workspace block ends or ended. Omitted for a campaign, which stays paused until\nresumed. A workspace hold is renewed until released, so while active this is only its current expiry.",
            "format": "date-time",
            "nullable": true
          },
          "isActive": {
            "type": "boolean",
            "description": "The target is still blocked or paused now."
          }
        },
        "additionalProperties": false,
        "description": "One inbox, domain, campaign or workspace Ken paused on its own (DEV-2025)."
      },
      "AutonomousReplySettingsModel": {
        "type": "object",
        "properties": {
          "defaultEnabled": {
            "type": "boolean"
          },
          "linkedInEnabled": {
            "type": "boolean"
          },
          "mode": {
            "type": "string",
            "nullable": true
          },
          "extraInstructions": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AvailabilityOverrideModel": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "nullable": true
          },
          "ranges": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AvailabilityRangeModel": {
        "type": "object",
        "properties": {
          "start": {
            "type": "string",
            "nullable": true
          },
          "end": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AvailabilityScheduleModel": {
        "type": "object",
        "properties": {
          "timeZone": {
            "type": "string",
            "nullable": true
          },
          "weekly": {
            "$ref": "#/components/schemas/AvailabilityWeekModel"
          },
          "overrides": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityOverrideModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AvailabilityWeekModel": {
        "type": "object",
        "properties": {
          "monday": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          },
          "tuesday": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          },
          "wednesday": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          },
          "thursday": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          },
          "friday": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          },
          "saturday": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          },
          "sunday": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailabilityRangeModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "AvailableCallingNumberModel": {
        "type": "object",
        "properties": {
          "e164": {
            "type": "string",
            "nullable": true
          },
          "countryIso2": {
            "type": "string",
            "nullable": true
          },
          "locality": {
            "type": "string",
            "nullable": true
          },
          "region": {
            "type": "string",
            "nullable": true
          },
          "monthlyCredits": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false,
        "description": "A local number Telnyx offers for sale."
      },
      "BlocklistBulkDeleteFailure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "error": {
            "$ref": "#/components/schemas/BlocklistBulkError"
          }
        },
        "additionalProperties": false
      },
      "BlocklistBulkDeleteResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Every id off the blocklist after the call, removed now or already gone, in request order.",
            "nullable": true
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlocklistBulkDeleteFailure"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Result of `POST /v1/blocklist-entries/bulk-delete`."
      },
      "BlocklistBulkError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "`invalid_state`: an own-domain entry, or a rule entry while blocklist rules are on.",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BlocklistBulkFailure": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "nullable": true
          },
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BlocklistBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlocklistEntryModel"
            },
            "nullable": true
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlocklistBulkFailure"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BlocklistEntryCounts": {
        "type": "object",
        "properties": {
          "all": {
            "type": "integer",
            "format": "int32"
          },
          "emails": {
            "type": "integer",
            "format": "int32"
          },
          "domains": {
            "type": "integer",
            "format": "int32"
          },
          "fromCrm": {
            "type": "integer",
            "description": "Entries a customer account or a blocklist rule holds (`customer` and `rule`).",
            "format": "int32"
          },
          "noReason": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "How many entries the workspace has per Settings > Blocklist filter. The list's filters do not narrow them."
      },
      "BlocklistEntryListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlocklistEntryModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          },
          "counts": {
            "$ref": "#/components/schemas/BlocklistEntryCounts"
          }
        },
        "additionalProperties": false,
        "description": "The list envelope of `GET /v1/blocklist-entries`, with the filter counts when asked for."
      },
      "BlocklistEntryModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "source": {
            "type": "string",
            "description": "`manual`, or `own_domain` for a domain mirrored from the workspace's own domains (DEV-1758).\n            An `own_domain` entry cannot be deleted here (`409 invalid_state`); remove the domain in\n            Settings > Company instead, or ask Kenso support to change the Primary domain. `customer` for a domain of an\n            account marked a customer (DEV-3354); clearing the account's Customer flag removes it. `rule` for a domain a\n            blocklist rule adds from Kenso's CRM (DEV-3903): it comes off once no enabled rule matches it, and it cannot be\n            deleted here (`409 invalid_state`); change or turn off the rule instead. Adding the same value here makes it\n            `manual`.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why the value is blocked, at most 200 characters. Omitted when the entry has none. Kenso sets it on rows it adds\n(`Opted out or bounced`, `Customer in HubSpot`, `Customer account`); own-domain rows have none.",
            "nullable": true
          },
          "claimed": {
            "type": "boolean",
            "description": "`true` on a create or bulk-create result when a customer account or a blocklist rule already listed the domain\n            and this call made that entry `manual`, same id. Omitted otherwise.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 7712,
          "type": "domain",
          "value": "competitor.example.com",
          "createdAt": "2026-09-23T15:02:11Z",
          "source": "manual",
          "reason": "Current customer"
        }
      },
      "BlocklistImportModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BlocklistRuleCrmListModel": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "objectType": {
            "type": "string",
            "nullable": true
          },
          "members": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "readAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BlocklistRuleCrmSampleModel": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BlocklistRuleMatchesModel": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "integer",
            "format": "int32"
          },
          "domains": {
            "type": "integer",
            "format": "int32"
          },
          "people": {
            "type": "integer",
            "format": "int32"
          },
          "crmRecords": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "BlocklistRuleModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "stages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "accountTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "enabled": {
            "type": "boolean"
          },
          "position": {
            "type": "integer",
            "format": "int32"
          },
          "releaseAfterDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "crmConnectionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "crmLifecycles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "crmList": {
            "$ref": "#/components/schemas/BlocklistRuleCrmListModel"
          },
          "matches": {
            "$ref": "#/components/schemas/BlocklistRuleMatchesModel"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "BlocklistRulePreviewModel": {
        "type": "object",
        "properties": {
          "accounts": {
            "type": "integer",
            "format": "int32"
          },
          "domains": {
            "type": "integer",
            "format": "int32"
          },
          "people": {
            "type": "integer",
            "format": "int32"
          },
          "crmRecords": {
            "type": "integer",
            "format": "int32"
          },
          "alreadyBlocked": {
            "type": "integer",
            "format": "int32"
          },
          "sample": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlocklistRuleSampleModel"
            },
            "nullable": true
          },
          "crmSample": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlocklistRuleCrmSampleModel"
            },
            "nullable": true
          },
          "skipped": {
            "$ref": "#/components/schemas/BlocklistRuleSkippedModel"
          }
        },
        "additionalProperties": false
      },
      "BlocklistRuleSampleModel": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "domain": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BlocklistRuleSkippedModel": {
        "type": "object",
        "properties": {
          "noDomain": {
            "type": "integer",
            "format": "int32"
          },
          "noEmail": {
            "type": "integer",
            "format": "int32"
          },
          "freeMail": {
            "type": "integer",
            "format": "int32"
          },
          "released": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "BookingBookerModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BookingLeaverItemModel": {
        "required": [
          "bookingId",
          "status"
        ],
        "type": "object",
        "properties": {
          "bookingId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "startAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "newBookingId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "hostMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "calendarEventRemoved": {
            "type": "boolean",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BookingLeaverRequest": {
        "type": "object",
        "properties": {
          "hostMemberId": {
            "type": "integer",
            "description": "The former member whose upcoming bookings to handle.",
            "format": "int64",
            "nullable": true
          },
          "cursor": {
            "type": "string",
            "description": "The previous answer's nextCursor; null for the first call.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of POST /v1/bookings/bulk-reassign and bulk-cancel (DEV-1964)."
      },
      "BookingLeaverResultModel": {
        "required": [
          "failed",
          "hasMore",
          "results",
          "succeeded"
        ],
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "integer",
            "format": "int32"
          },
          "failed": {
            "type": "integer",
            "format": "int32"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BookingLeaverItemModel"
            },
            "nullable": true
          },
          "hasMore": {
            "type": "boolean"
          },
          "nextCursor": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One page of a bulk reassign or cancel (DEV-1964 D10)."
      },
      "BookingLinkModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "availability": {
            "$ref": "#/components/schemas/AvailabilityScheduleModel"
          }
        },
        "additionalProperties": false
      },
      "BookingLinkSummaryModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "meetingTypeId": {
            "type": "integer",
            "format": "int64"
          },
          "personId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "availability": {
            "$ref": "#/components/schemas/AvailabilityScheduleModel"
          }
        },
        "additionalProperties": false
      },
      "BookingModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "meetingTypeId": {
            "type": "integer",
            "format": "int64"
          },
          "hostMemberId": {
            "type": "integer",
            "format": "int64"
          },
          "organizerMemberId": {
            "type": "integer",
            "format": "int64"
          },
          "startAt": {
            "type": "string",
            "format": "date-time"
          },
          "endAt": {
            "type": "string",
            "format": "date-time"
          },
          "bookerTimeZone": {
            "type": "string",
            "nullable": true
          },
          "booker": {
            "$ref": "#/components/schemas/BookingBookerModel"
          },
          "bookerPhone": {
            "type": "string",
            "nullable": true
          },
          "answers": {
            "type": "object",
            "additionalProperties": { },
            "nullable": true
          },
          "personId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "accountId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "meetingId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "touchId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "assetId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "bookingLinkId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "routingReason": {
            "type": "string",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "calendarEmail": {
            "type": "string",
            "nullable": true
          },
          "cancelReason": {
            "type": "string",
            "nullable": true
          },
          "cancelledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "rescheduledFromBookingId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "BrandByHostModel": {
        "type": "object",
        "properties": {
          "hostname": {
            "type": "string",
            "nullable": true
          },
          "productName": {
            "type": "string",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "nullable": true
          },
          "faviconUrl": {
            "type": "string",
            "nullable": true
          },
          "auth0OrganizationId": {
            "type": "string",
            "description": "Auth0 organization the login on this host uses. Omitted while the workspace has none.",
            "nullable": true
          },
          "accentColor": {
            "type": "string",
            "description": "Accent color, `#RRGGBB` uppercase. Omitted when the Kenso default applies.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "`GET /v1/brands/by-host`: the public brand of a verified custom host. Name, logo, and favicon\n            carry the Kenso defaults when the brand has not customized them."
      },
      "BugReportReceiptModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "Always `received`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A filed bug report (DEV-6152). The reporter never sees a Linear id or URL."
      },
      "BulkContactSequenceRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "1 to 1,000 contact ids in the workspace.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/contacts/bulk-pause` and `POST /v1/contacts/bulk-resume`."
      },
      "BulkCreateBlocklistEntriesRequest": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "values": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The values to block. Send this or Ken.Scraper.API.Dtos.BulkCreateBlocklistEntriesRequest.Entries, not both.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why every value is blocked. Optional, at most 200 characters. An entry's own reason wins over it.",
            "nullable": true
          },
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkCreateBlocklistEntry"
            },
            "description": "Values with their own reason, such as a CSV reason column. Send this or Ken.Scraper.API.Dtos.BulkCreateBlocklistEntriesRequest.Values, not both.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BulkCreateBlocklistEntry": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why this value is blocked. Optional, at most 200 characters.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BulkDeleteBlocklistEntriesRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "The entry ids to remove, at most 1,000.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BulkDeleteContactsRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BulkRestoreContactsRequest": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "1 to 1,000 contact ids in the workspace.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/contacts/bulk-restore`, the same shape as bulk-delete (DEV-5219)."
      },
      "BulkTagAssignmentRequest": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagAssignmentRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/tags/{tagId}/assignments/bulk-create` and `bulk-delete`.\nEach item has the shape of Ken.Scraper.API.Dtos.TagAssignmentRequest."
      },
      "BulkUpdateContactItemBody": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "description": "First name. Null clears it.",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "description": "Last name. Null clears it.",
            "nullable": true
          },
          "title": {
            "type": "string",
            "description": "Job title. Null clears it.",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "description": "LinkedIn profile URL. Null clears it.",
            "nullable": true
          },
          "location": {
            "type": "string",
            "description": "Location. Null clears it.",
            "nullable": true
          },
          "email": {
            "type": "string",
            "description": "Primary email address. Null removes it; an invalid address is refused.",
            "nullable": true
          },
          "isQualified": {
            "type": "boolean",
            "description": "Whether the contact is qualified. Must be true or false: null is refused."
          },
          "doNotContact": {
            "type": "boolean",
            "description": "Whether the contact must never be contacted. Must be true or false: null is refused."
          },
          "outreachLanguage": {
            "type": "string",
            "description": "Outreach language set by hand: a locale whose language has a market pack or a country entry, such as fr-FR, es-MX or\nde. It is locked, so no import, enrichment or reply replaces it. Null clears and unlocks it.",
            "nullable": true
          },
          "customVariables": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "nullable": true
            },
            "description": "Merge into the contact's custom variables. A null or empty value removes that key. Omit to leave them unchanged.",
            "nullable": true
          },
          "customImageUrl": {
            "type": "string",
            "description": "The lead's own image, shown in emails as `{{custom_image}}`: a public https URL of at most 2048 characters that\nKenso downloads and hosts. Empty or null clears it. Needs campaign images on the workspace.",
            "nullable": true
          },
          "contactId": {
            "type": "integer",
            "description": "Required. The contact to update. Positive, and not repeated within the request.",
            "format": "int64"
          }
        },
        "additionalProperties": false,
        "description": "One item of `POST /v1/contacts/bulk-update`: a `contactId` plus any field `PATCH /v1/contacts/{contactId}`\naccepts, with the same semantics. An absent property leaves that field unchanged, and `null` clears a string field."
      },
      "BulkUpdateContactsBody": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BulkUpdateContactItemBody"
            },
            "description": "Required. The contacts to update, in request order.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/contacts/bulk-update`: 1 to 1,000 items, each with a distinct `contactId`."
      },
      "BulkUpdateContactsRequest": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": { },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/contacts/bulk-update`. Each item is a `contactId` plus any fields\n`PATCH /v1/contacts/{contactId}` accepts, with the same semantics."
      },
      "BuyCallingNumberRequest": {
        "type": "object",
        "properties": {
          "e164": {
            "type": "string",
            "description": "The number to buy, from `numbers/available`. When a fresh search no longer offers it, the first\n            number that search offers is bought instead.",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "areaCode": {
            "type": "string",
            "nullable": true
          },
          "locality": {
            "type": "string",
            "nullable": true
          },
          "assignedMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "cnam": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "POST /v1/calling/numbers body. Toll-free numbers are not sold."
      },
      "BuyerPreviewCompanyFactsModel": {
        "type": "object",
        "properties": {
          "kenCompanyId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "domain": {
            "type": "string",
            "nullable": true
          },
          "employeeCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "industry": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BuyerPreviewCompanyInput": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "domain": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BuyerPreviewCompanyModel": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "input": {
            "$ref": "#/components/schemas/BuyerPreviewInputModel"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "unmatchedReason": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "$ref": "#/components/schemas/BuyerPreviewCompanyFactsModel"
          },
          "signal": {
            "$ref": "#/components/schemas/BuyerPreviewSignalModel"
          },
          "people": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BuyerPreviewPersonModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BuyerPreviewInputModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "domain": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BuyerPreviewModel": {
        "type": "object",
        "properties": {
          "icp": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BuyerPreviewCompanyModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "BuyerPreviewPersonModel": {
        "type": "object",
        "properties": {
          "kenPersonId": {
            "type": "integer",
            "format": "int64"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "seniorityLevel": {
            "type": "string",
            "nullable": true
          },
          "function": {
            "type": "string",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "weakMatch": {
            "type": "boolean"
          },
          "contact": {
            "$ref": "#/components/schemas/SearchContactDTO"
          }
        },
        "additionalProperties": false
      },
      "BuyerPreviewSignalModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CallingCallModel": {
        "type": "object",
        "properties": {
          "callId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "description": "`ringing_rep` while the member's browser rings.",
            "nullable": true
          },
          "to": {
            "type": "string",
            "description": "The number called (E.164).",
            "nullable": true
          },
          "from": {
            "type": "string",
            "description": "The number the call shows (E.164).",
            "nullable": true
          },
          "fromNumberId": {
            "type": "integer",
            "format": "int64"
          },
          "millicreditsPerMinute": {
            "type": "integer",
            "description": "The destination rate plus the rep's leg, per started minute of each.",
            "format": "int64"
          },
          "consentNoticeWillPlay": {
            "type": "boolean",
            "description": "The prospect hears \"This call may be recorded.\" before the legs are bridged."
          },
          "recordingAllowed": {
            "type": "boolean"
          },
          "lineType": {
            "type": "string",
            "description": "The number's line type, like `mobile` or `fixed_line`.",
            "nullable": true
          },
          "voicemailDropMode": {
            "type": "string",
            "description": "`off`, `manual` or `auto`, from the workspace's setting and the line type. Not off: Kenso listens for a\n            voicemail beep, and a greeting can be dropped (`manual`: with `POST .../voicemail-drop`; `auto`: the\n            member's oldest greeting drops by itself).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A browser call Kenso started (Dialer 05). The member's browser rings first; the prospect is dialed when it answers."
      },
      "CallingHangupModel": {
        "type": "object",
        "properties": {
          "callId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A hangup of a browser call: the call's status now."
      },
      "CallingNumberModel": {
        "type": "object",
        "properties": {
          "numberId": {
            "type": "integer",
            "format": "int64"
          },
          "e164": {
            "type": "string",
            "nullable": true
          },
          "countryIso2": {
            "type": "string",
            "nullable": true
          },
          "numberType": {
            "type": "string",
            "description": "`local` (toll-free numbers are not sold yet).",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`ordering`, `active`, `releasing` or `released`.",
            "nullable": true
          },
          "assignedMemberId": {
            "type": "integer",
            "description": "The member who calls from it; null when nobody has it.",
            "format": "int64",
            "nullable": true
          },
          "cnam": {
            "type": "string",
            "description": "The caller name shown with its calls (US numbers only, at most 15 characters).",
            "nullable": true
          },
          "monthlyCredits": {
            "type": "integer",
            "format": "int64"
          },
          "unpaid": {
            "type": "boolean",
            "description": "True when its monthly credits could not be charged: outbound calls from it are refused until they are."
          },
          "orderedAt": {
            "type": "string",
            "format": "date-time"
          },
          "activatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "releasedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A phone number the workspace bought in Kenso. It costs `monthlyCredits` credits a month."
      },
      "CallingRateModel": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "nullable": true
          },
          "countryIso2": {
            "type": "string",
            "nullable": true
          },
          "lineType": {
            "type": "string",
            "description": "The number's line type, like `mobile`, `fixed_line` or `fixed_line_or_mobile`.",
            "nullable": true
          },
          "priced": {
            "type": "boolean"
          },
          "millicreditsPerMinute": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "recordingMillicreditsPerMinute": {
            "type": "integer",
            "description": "Added per minute when the call is recorded.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What a call to one destination costs per minute. `millicreditsPerMinute` is the destination rate plus the\nrep's leg; with `priced: false` the destination cannot be called yet and both rates are null."
      },
      "CallingSettingsModel": {
        "type": "object",
        "properties": {
          "recordingEnabled": {
            "type": "boolean",
            "description": "Record calls (both sides, dual channel)."
          },
          "consentNotice": {
            "type": "string",
            "description": "When the recording notice plays: `auto` (where the law asks for it), `always` or `never`.",
            "nullable": true
          },
          "voicemailDropMode": {
            "type": "string",
            "description": "`off`, `manual` (the rep drops one) or `auto`.",
            "nullable": true
          },
          "voicemailToMobile": {
            "type": "boolean",
            "description": "Drop voicemails on mobile numbers too. Turning it on needs `acceptTcpaNotice: true`."
          },
          "voicemailToMobileAcceptedByMemberId": {
            "type": "integer",
            "description": "Read-only. Who last accepted the TCPA notice; kept when the switch goes off.",
            "format": "int64",
            "nullable": true
          },
          "voicemailToMobileAcceptedAt": {
            "type": "string",
            "description": "Read-only. When the TCPA notice was last accepted.",
            "format": "date-time",
            "nullable": true
          },
          "allowedCountries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ISO 3166 alpha-2 countries the workspace calls; each one Kenso supports (US, CA).",
            "nullable": true
          },
          "dncScrub": {
            "type": "boolean",
            "description": "Scrub numbers against do-not-call lists before calling."
          },
          "updatedAt": {
            "type": "string",
            "description": "Read-only. Last save; null while the workspace runs on the defaults.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A workspace's calling settings (Dialer 02, DEV-3327). No row reads as the defaults with `updatedAt` null."
      },
      "CallingSpendLimitModel": {
        "type": "object",
        "properties": {
          "monthlyLimitMillicredits": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "isDefault": {
            "type": "boolean",
            "description": "True while the cap is the default, 2,000 credits a month."
          },
          "spentThisMonthMillicredits": {
            "type": "integer",
            "description": "Call minutes and recordings charged this UTC month, plus open call holds: the same spend the cap counts. Number\nfees are not in it.",
            "format": "int64"
          }
        },
        "additionalProperties": false,
        "description": "The workspace's monthly calling cap (null is no limit) and what calling spent this UTC month."
      },
      "CallingTokenModel": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "nullable": true
          },
          "sipUsername": {
            "type": "string",
            "description": "The member's SIP username; a call start dials it.",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A Telnyx WebRTC login token for the member's browser. A secret: keep it in memory."
      },
      "CallingVoicemailDropModel": {
        "type": "object",
        "properties": {
          "callId": {
            "type": "integer",
            "format": "int64"
          },
          "voicemailId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "voicemailDropStatus": {
            "type": "string",
            "description": "`requested` (waiting for the beep, which never comes when detection heard no machine: a drop you ask for\n            then plays at once), `starting` (Kenso is hanging up your side), `playing`,\n            `dropped` or `failed`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A voicemail drop on a browser call (Dialer 08)."
      },
      "CallingVoicemailModel": {
        "type": "object",
        "properties": {
          "voicemailId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "durationSeconds": {
            "type": "integer",
            "description": "Whole seconds, rounded up.",
            "format": "int32"
          },
          "format": {
            "type": "string",
            "description": "`wav` or `mp3`.",
            "nullable": true
          },
          "audioUrl": {
            "type": "string",
            "description": "A link to listen to it, valid for 5 minutes. Absent while Kenso's audio store is not set up.",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "One of the member's voicemail greetings (Dialer 08)."
      },
      "CampaignAiWorkflowModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Workflow id: 1 qualification, 2 personalization, 3 rewriting, 4 segmentation, 6 scoring, 8 line check.",
            "format": "int64"
          },
          "flow": {
            "type": "string",
            "description": "`qualification`, `personalization`, `rewriting`, `segmentation`, `scoring`, or\n            `line_check`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "An AI workflow attached to a campaign."
      },
      "CampaignComplianceCountryModel": {
        "type": "object",
        "properties": {
          "iso2": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "regime": {
            "type": "string",
            "nullable": true
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "contactCount": {
            "type": "integer",
            "format": "int32"
          },
          "acknowledgedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "acknowledgedByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One consent-first country: `iso2` (`ES`), `name`, `regime` (`opt_out`, `consent` or\n`unresolved`), `note` (a short summary of the rule, not legal advice), `sources` (public pages),\n`contactCount` (the campaign's live contacts there), and who acknowledged it when (absent until someone does;\n`acknowledgedByUserId` is absent for an API key not bound to a user)."
      },
      "CampaignComplianceModel": {
        "type": "object",
        "properties": {
          "acknowledgementRequired": {
            "type": "boolean"
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignComplianceCountryModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A campaign's consent-first countries (DEV-1923): the countries its contacts sit in whose cold email rules launch asks\nsomeone to acknowledge, once each. `acknowledgementRequired` is true while any of them has no acknowledgement; launch\nthen answers 409 `acknowledgement_required`. Empty for a campaign with no contacts in such a country."
      },
      "CampaignForecastModel": {
        "type": "object",
        "properties": {
          "plannedSendCount": {
            "type": "integer",
            "description": "Sends planned for the whole campaign: Ken.Scraper.API.Canonical.CampaignForecastModel.SentCount plus Ken.Scraper.API.Canonical.CampaignForecastModel.RemainingSendCount.",
            "format": "int32"
          },
          "sentCount": {
            "type": "integer",
            "description": "Sends made so far, the campaign's sent total the forecast used. It is rolled up from daily\nstats, so the current day's sends can show up the next day.",
            "format": "int32"
          },
          "remainingSendCount": {
            "type": "integer",
            "description": "Sends still planned, for the leads in the campaign and the steps they have left.",
            "format": "int32"
          },
          "progress": {
            "type": "number",
            "description": "Ken.Scraper.API.Canonical.CampaignForecastModel.SentCount over Ken.Scraper.API.Canonical.CampaignForecastModel.PlannedSendCount, a fraction from 0 to 1 (four\n            decimals). Progress against planned sends, not the share of leads contacted.",
            "format": "double"
          },
          "estimatedFinishAt": {
            "type": "string",
            "description": "When the last planned send should go out (UTC). Present only while the campaign is sending and\nthe forecast can place every remaining send; omitted while paused, when no inbox has capacity\nfor it, when the sending window is unusable, or when it is more than two years out.",
            "format": "date-time",
            "nullable": true
          },
          "effectiveDailyCapacity": {
            "type": "integer",
            "description": "Sends a day this campaign gets while sending; 0 when no inbox has capacity for it. Omitted while\npaused, when unknown, and until the first forecast after a resume (up to about 5 minutes).",
            "format": "int32",
            "nullable": true
          },
          "calculatedAt": {
            "type": "string",
            "description": "When the forecast was computed (UTC). Under 24 hours old, or the forecast is omitted.",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "DEV-2541: how far a sending or paused campaign is against its planned sends, and when it should\nfinish. From the sequencer's stored forecast, refreshed every 5 minutes from the inboxes' daily\ncapacity (shared with the workspace's other campaigns), `maxEmailsPerDay`, the sending days,\nwindow and time zone, and the step waits."
      },
      "CampaignImageModel": {
        "type": "object",
        "properties": {
          "imageKey": {
            "type": "string",
            "nullable": true
          },
          "contactId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "variableKey": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "errorDetail": {
            "type": "string",
            "nullable": true
          },
          "width": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "height": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "previewUrl": {
            "type": "string",
            "nullable": true
          },
          "previewExpiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "The canonical CampaignImage (DEV-6700; tasks 11 and 12 write this file byte for byte the same)."
      },
      "CampaignLanguageMixModel": {
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "nullable": true
          },
          "contacts": {
            "type": "integer",
            "format": "int32"
          },
          "lowConfidence": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "The campaign's contacts of one outreach language, and how many of them are low confidence."
      },
      "CampaignLanguagePackModel": {
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A market pack: `locale` (`fr-FR`), its own-language `name`, `status``supported` or `tested`."
      },
      "CampaignLanguagesModel": {
        "type": "object",
        "properties": {
          "sourceLanguage": {
            "type": "string",
            "nullable": true
          },
          "languageMode": {
            "type": "string",
            "nullable": true
          },
          "enabledLanguages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "formalityOverrides": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "languageFallback": {
            "type": "string",
            "nullable": true
          },
          "available": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignLanguagePackModel"
            },
            "nullable": true
          },
          "mix": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignLanguageMixModel"
            },
            "nullable": true
          },
          "unresolved": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A campaign's languages (DEV-1921 decision 20): the five settings as `CampaignModel` carries them, the market packs\nit can enable (`status``supported` or `tested`, drafts left out), and its contacts that can still be\ncontacted per outreach language. `mix[].lowConfidence` of a locale's `contacts` are under the routing floor\nand get the source language; `unresolved` have no outreach language yet."
      },
      "CampaignListModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "listType": {
            "type": "string",
            "nullable": true
          },
          "sourceCampaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "contactCount": {
            "type": "integer",
            "format": "int32"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 3305,
          "campaignId": 4821,
          "name": "SaaS engineering leaders - October.csv",
          "listType": "csv",
          "contactCount": 1840,
          "status": "done",
          "createdAt": "2026-09-23T15:02:11Z",
          "modifiedAt": "2026-09-23T15:09:48Z"
        }
      },
      "CampaignLocalizationModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "stepId": {
            "type": "integer",
            "format": "int64"
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "language": {
            "type": "string",
            "nullable": true
          },
          "subjectLine": {
            "type": "string",
            "nullable": true
          },
          "bodyContent": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "generating": {
            "type": "boolean"
          },
          "sourceHash": {
            "type": "string",
            "nullable": true
          },
          "stale": {
            "type": "boolean"
          },
          "packVersion": {
            "type": "string",
            "nullable": true
          },
          "mirrorLanguage": {
            "type": "string",
            "nullable": true
          },
          "mirrorSubject": {
            "type": "string",
            "nullable": true
          },
          "mirrorBody": {
            "type": "string",
            "nullable": true
          },
          "qaScore": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "qaReport": {
            "$ref": "#/components/schemas/CampaignLocalizationQaReportModel"
          },
          "editedByHuman": {
            "type": "boolean"
          },
          "approvedByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "approvedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "One step of a campaign in one language (DEV-1921 decision 22). `channel` is `email` or `linkedin`;\n`variant` is `a` to `d`; `status` is `draft`, `approved`, `stale`,\n`needs_review` or `failed`. `generating`: the localization job has it queued. `stale`: marked stale,\nor written from older source text or an older market pack. A LinkedIn row has no subject."
      },
      "CampaignLocalizationQaErrorModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One finding. A judge finding has the code `judge`."
      },
      "CampaignLocalizationQaReportModel": {
        "type": "object",
        "properties": {
          "passed": {
            "type": "boolean"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignLocalizationQaErrorModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The quality check of a localization: whether it passed, and the rule and judge findings."
      },
      "CampaignMailProvidersModel": {
        "type": "object",
        "properties": {
          "gateways": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MailProviderCountModel"
            },
            "description": "Every active gateway in the catalog, 0 included, most contacts first.",
            "nullable": true
          },
          "mailboxProviders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MailProviderCountModel"
            },
            "description": "Every active mailbox host and forwarder in the catalog, 0 included, most contacts first.",
            "nullable": true
          },
          "pendingCount": {
            "type": "integer",
            "description": "Contacts whose email domain is not checked for a gateway yet.",
            "format": "int32"
          },
          "isPartial": {
            "type": "boolean",
            "description": "True when the campaign has more contacts than one read scans (100,000), so the counts are a floor."
          }
        },
        "additionalProperties": false,
        "description": "DEV-5062: how a campaign's contacts split by security gateway and by mailbox host."
      },
      "CampaignMigrationOriginModel": {
        "type": "object",
        "properties": {
          "connectionId": {
            "type": "integer",
            "format": "int64"
          },
          "vendor": {
            "type": "string",
            "nullable": true
          },
          "sourceAccountId": {
            "type": "string",
            "nullable": true
          },
          "sourceCampaignId": {
            "type": "string",
            "nullable": true
          },
          "sourceStatus": {
            "type": "string",
            "nullable": true
          },
          "syncedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "cutoverAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "historyFrom": {
            "type": "string",
            "description": "DEV-3268: the first day (`YYYY-MM-DD`) of the campaign's imported daily stats, so Analytics can open on the\nimported range. Null when none were imported; sent as null, not omitted.",
            "nullable": true
          },
          "historyTo": {
            "type": "string",
            "description": "DEV-3268: the last day (`YYYY-MM-DD`) of the campaign's imported daily stats. Null with Ken.Scraper.API.Canonical.CampaignMigrationOriginModel.HistoryFrom.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-2327: the tool, account and campaign an imported campaign came from. `sourceStatus` is the campaign's status\nthere at the last sync (`active`, `paused`, ... or `unknown`)."
      },
      "CampaignModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "contactLimit": {
            "type": "integer",
            "description": "The campaign's contact limit. DEV-3765: a monthly number when Ken.Scraper.API.Canonical.CampaignModel.ContactLimitPeriod is `month`\n(new qualified contacts with a Safe email per UTC calendar month), a lifetime total when it is `total`.",
            "format": "int32"
          },
          "contactLimitPeriod": {
            "type": "string",
            "description": "DEV-3765: `month` or `total`, what Ken.Scraper.API.Canonical.CampaignModel.ContactLimit counts.",
            "nullable": true
          },
          "contactLimitUsed": {
            "type": "integer",
            "description": "DEV-3765: contacts counted against Ken.Scraper.API.Canonical.CampaignModel.ContactLimit: this month's when monthly, else Ken.Scraper.API.Canonical.CampaignModel.ContactCount.",
            "format": "int32"
          },
          "contactLimitResetsAt": {
            "type": "string",
            "description": "DEV-3765: when a monthly count starts again (the next 1st, 00:00 UTC). Omitted for a total.",
            "format": "date-time",
            "nullable": true
          },
          "fairUseContactLimit": {
            "type": "integer",
            "description": "DEV-3765: lifetime fair-use ceiling of a monthly limit. Omitted for a total.",
            "format": "int32",
            "nullable": true
          },
          "contactLimitReached": {
            "type": "boolean",
            "description": "True while processing is stopped by the contact limit, the fair-use total or the workspace's lead credits."
          },
          "contactLimitReachedReason": {
            "type": "string",
            "description": "DEV-3765: why Ken.Scraper.API.Canonical.CampaignModel.ContactLimitReached is set: `monthly_limit`, `contact_limit`,\n`fair_use` or `lead_credits`. Omitted otherwise.",
            "nullable": true
          },
          "contactCount": {
            "type": "integer",
            "description": "Contacts found with a valid email (`campaign.valid_contacts_found`). See Ken.Scraper.API.Canonical.CampaignModel.LeadCount.",
            "format": "int32"
          },
          "leadCount": {
            "type": "integer",
            "description": "DEV-2825: every non-deleted contact in the campaign, with or without an email, so a LinkedIn-only campaign\ncounts its leads. Returned on the list (one count for the page, DEV-3034; cached per workspace, DEV-6843, so it\nusually lags by under 15 minutes, and on a very large workspace the first list after a quiet period can show an\nolder count until the next list) and on the single-campaign responses of `/v1/campaigns` (get, create, update,\nduplicate and the lifecycle actions), which count live. Omitted when the count cannot be read, or does not\nfinish within its 1 s budget on a very large workspace.",
            "format": "int32",
            "nullable": true
          },
          "segmentCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "inboxCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "launchedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "sourceStatus": {
            "type": "string",
            "description": "Stored `campaign.status` (pipeline/source), not the collapsed lifecycle string.",
            "nullable": true
          },
          "sendingStatus": {
            "type": "string",
            "description": "Snake-case `sending_status`. Sending is `sending` while Ken.Scraper.API.Canonical.CampaignModel.Status is `active`.",
            "nullable": true
          },
          "processingStatus": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Snake-case processing flags. `none` when the flags value is 0.",
            "nullable": true
          },
          "sendingDays": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "sendingStartTime": {
            "type": "string",
            "nullable": true
          },
          "sendingEndTime": {
            "type": "string",
            "nullable": true
          },
          "sendingTimezone": {
            "type": "string",
            "nullable": true
          },
          "maxEmailsPerDay": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "sendingError": {
            "type": "string",
            "description": "DEV-1366: current sending error (failure class, count in the window, affected inboxes).\nSet while hard send failures stay above the rate rule; clears itself. Null = none.",
            "nullable": true
          },
          "sendingErrorAt": {
            "type": "string",
            "description": "UTC instant the current Ken.Scraper.API.Canonical.CampaignModel.SendingError began. Null with it.",
            "format": "date-time",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "description": "DEV-1753 campaign owner, a workspace member id. The stored owner when one was set, else the\nmember who created the campaign while they are still in the workspace. Omitted when neither.",
            "format": "int64",
            "nullable": true
          },
          "stopOnReply": {
            "type": "boolean",
            "description": "The lead's reply stops their sequence. When false, neutral and positive replies keep it\ngoing; a negative reply, an unsubscribe, or a booked meeting still stops it.\nThe four sending switches take effect only with the `campaign_send_settings` flag on\nfor the workspace; this field is the stored value either way."
          },
          "stopCompanyOnReply": {
            "type": "boolean",
            "description": "A reply also stops every other contact at the lead's company. Change it with\n`PATCH /v1/campaigns/{campaignId}` or the LinkedIn settings (the same stored value). New\ncampaigns start with it on (DEV-3060); a duplicate keeps its source's value. False when the campaign\nhas no LinkedIn settings."
          },
          "groupSameCompanySends": {
            "type": "boolean",
            "description": "DEV-1661: coworkers at one company share a send day. New campaigns default to true."
          },
          "newLeadsFirst": {
            "type": "boolean",
            "description": "DEV-3762: first emails (step 1) take the campaign's daily capacity ahead of its follow-ups, so every lead gets\nemail 1 before older leads get their next step. False (the default) sends due follow-ups first. On a campaign\nthat keeps getting new leads (top-ups, imports), follow-ups can wait as long as it stays on, so turn it off once\nKen.Scraper.API.Canonical.CampaignModel.AwaitingFirstEmailCount reaches 0. Every copy starts with it off, unlike the other sending\nswitches: a duplicate, a template saved from the campaign, and a draft made from that template."
          },
          "sourceLanguage": {
            "type": "string",
            "description": "DEV-1921: the language the steps are written in, a market pack locale (`fr-FR`) or a bare language\n(`en`, the default). Always on the wire, like the other four language settings. Changing any of them needs\nthe `multilingual_outreach` flag for the workspace.",
            "nullable": true
          },
          "languageMode": {
            "type": "string",
            "description": "DEV-1921: `source_only` (default) sends every contact the source text. `auto` sends a contact the\napproved localization of their outreach language when Ken.Scraper.API.Canonical.CampaignModel.EnabledLanguages lists it.",
            "nullable": true
          },
          "enabledLanguages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-1921: the market pack locales the campaign localizes into (`fr-FR`, `es-MX`). Empty: none.",
            "nullable": true
          },
          "formalityOverrides": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "DEV-1921: locale to `formal` or `informal`, over the pack's default. Empty: the packs' defaults.",
            "nullable": true
          },
          "languageFallback": {
            "type": "string",
            "description": "DEV-1921: what an `auto` campaign does for a contact whose language has no approved localization:\n`source` (default) sends the source text, `hold` holds the contact until one is approved.",
            "nullable": true
          },
          "awaitingFirstEmailCount": {
            "type": "integer",
            "description": "DEV-3762: ready leads still waiting for their first email (no email sent and none accepted for sending).\nNot counted: leads in a paused segment or held back by the ready checks, company Cc members, bulk-paused leads\n(they get email 1 once resumed), and leads the sequencer never sends email 1 to (a sequence stop such as a\ncompany reply, a hard bounce, an unsubscribe).\nStill counted: leads waiting for campaign batch approval, leads an enforced account play holds, and leads whose\nemail is live in another campaign, so the count can stop falling above 0 while those wait. Returned on the\nsingle-campaign responses while Ken.Scraper.API.Canonical.CampaignModel.NewLeadsFirst is true; omitted otherwise, on the list, and when\nthe count cannot be read.",
            "format": "int32",
            "nullable": true
          },
          "rampUpDays": {
            "type": "integer",
            "description": "DEV-1661: ramp-up length in scheduled sending days, 0 (no ramp) to 30. New campaigns default to 5.",
            "format": "int32"
          },
          "trackClicks": {
            "type": "boolean",
            "description": "Links in sends go through tracking links. Stored value (see Ken.Scraper.API.Canonical.CampaignModel.StopOnReply)."
          },
          "trackOpens": {
            "type": "boolean",
            "description": "Sends carry the open-tracking pixel. Off by default. Stored value (see Ken.Scraper.API.Canonical.CampaignModel.StopOnReply)."
          },
          "unsubscribeLink": {
            "type": "boolean",
            "description": "Sends carry the `List-Unsubscribe` headers. When false they are left out of a step whose\nbody has the `{{unsubscribe_link}}` URL; a step without it keeps them, so every send has\nan opt-out. Stored value (see Ken.Scraper.API.Canonical.CampaignModel.StopOnReply)."
          },
          "protectAccountPlays": {
            "type": "boolean",
            "description": "DEV-1520: skip people in active account plays (warming, engaged, meeting_booked). New campaigns\ndefault to true. Takes effect only when account plays are on for the workspace."
          },
          "bookingMeetingTypeId": {
            "type": "integer",
            "description": "DEV-1963: the round robin meeting type that takes bookings the owner and sender can't. Omitted when none.",
            "format": "int64",
            "nullable": true
          },
          "replyTo": {
            "type": "string",
            "description": "DEV-2528: this campaign's Reply-To, over the workspace's. Omitted when the campaign uses the workspace's\n(or none). A connected inbox of this workspace; no header is sent from that same inbox.",
            "nullable": true
          },
          "excludedCountries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-5236: ISO 3166-1 alpha-2 codes (upper case, sorted) of the countries this campaign never sends to. Imports\ndrop a contact whose country is listed, and the sequencer skips one already on the campaign. A contact whose\ncountry Kenso cannot read is kept. Empty (the default) blocks none. Always on the wire.",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "DEV-1274: `sales` or `recruiting`. Set at create; PATCH refuses it.",
            "nullable": true
          },
          "roleId": {
            "type": "integer",
            "description": "DEV-1274: the primary role of a recruiting campaign, or null. Always on the wire.",
            "format": "int64",
            "nullable": true
          },
          "mode": {
            "type": "string",
            "description": "DEV-15: `batch` (a fixed audience) or `trigger` (signal-based: contacts arrive over time). A batch\ncampaign can become a trigger campaign; a trigger campaign cannot go back. Always on the wire.",
            "nullable": true
          },
          "autoLaunchWhenReady": {
            "type": "boolean",
            "description": "DEV-15: the campaign launches itself, and starts spending sending credits, once it reaches `ready`.\nChanging it needs the launch permission. Always on the wire."
          },
          "migration": {
            "$ref": "#/components/schemas/CampaignMigrationOriginModel"
          },
          "approvalsWaiting": {
            "type": "integer",
            "description": "DEV-1759: first-touch emails (leads) waiting for approval in the campaign's pending or rewriting campaign\nbatches. 0 when none.",
            "format": "int32"
          },
          "forecast": {
            "$ref": "#/components/schemas/CampaignForecastModel"
          },
          "pausedReason": {
            "$ref": "#/components/schemas/CampaignPausedReasonModel"
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 4821,
          "name": "Q4 SaaS founders",
          "status": "active",
          "channel": "email",
          "contactLimit": 2500,
          "contactLimitPeriod": "total",
          "contactLimitUsed": 1840,
          "contactLimitReached": false,
          "contactCount": 1840,
          "leadCount": 2115,
          "segmentCount": 2,
          "inboxCount": 6,
          "createdAt": "2026-09-23T15:02:11Z",
          "launchedAt": "2026-09-29T13:00:00Z",
          "sourceStatus": "done",
          "sendingStatus": "sending",
          "processingStatus": [
            "finished"
          ],
          "sendingDays": [
            1,
            2,
            3,
            4,
            5
          ],
          "sendingStartTime": "09:00",
          "sendingEndTime": "17:00",
          "sendingTimezone": "America/New_York",
          "maxEmailsPerDay": 300,
          "ownerMemberId": 1093,
          "stopOnReply": true,
          "stopCompanyOnReply": true,
          "groupSameCompanySends": true,
          "newLeadsFirst": false,
          "sourceLanguage": "en",
          "languageMode": "source_only",
          "enabledLanguages": [ ],
          "formalityOverrides": { },
          "languageFallback": "source",
          "rampUpDays": 5,
          "trackClicks": false,
          "trackOpens": false,
          "unsubscribeLink": true,
          "protectAccountPlays": true,
          "excludedCountries": [ ],
          "kind": "sales",
          "mode": "batch",
          "autoLaunchWhenReady": false,
          "approvalsWaiting": 0,
          "forecast": {
            "plannedSendCount": 3680,
            "sentCount": 2208,
            "remainingSendCount": 1472,
            "progress": 0.6,
            "estimatedFinishAt": "2026-10-20T20:40:00Z",
            "effectiveDailyCapacity": 300,
            "calculatedAt": "2026-10-14T09:35:00Z"
          }
        }
      },
      "CampaignPausedReasonModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What paused it; the values are listed on the type.",
            "nullable": true
          },
          "at": {
            "type": "string",
            "description": "When sending stopped (UTC). Omitted when no record names the time.",
            "format": "date-time",
            "nullable": true
          },
          "byMemberId": {
            "type": "integer",
            "description": "For `user` only: the member who paused it, or for whom an agent paused it. Omitted when unknown.",
            "format": "int64",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "description": "What was recorded, for display: the guard's evidence (`bounce_guard`, `sending_error`),\nwho paused it (`user`, for example \"Jordan Lee via Claude Code\"), or the system that did\n(`other`). Omitted otherwise.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-2541: why a campaign's sending is paused, from what Kenso recorded when it stopped.\n\n`kind`: `user` (a member paused it, or an agent for a member), `bounce_guard`\n(the campaign hard-bounce guard), `sending_error` (the sequencer paused it after repeated\nsend failures), `holiday` (the US-holiday pause), `client_approval` (paused for the\nclient's approval of changed copy or a lead list; approval resumes it, or leaves it paused for a\nmanual resume when it cannot send), `billing` (sending suspended for non-payment),\n`workspace_locked` (the workspace was deactivated or locked), `other` (another system\npause), `unknown` (nothing recorded why, such as a pause from before Kenso recorded them).\nClients must tolerate new values. A campaign is never paused for having no inboxes: a broken\ninbox leaves it sending and shows on the inbox instead."
      },
      "CampaignPerformanceBounceBreakdownModel": {
        "type": "object",
        "properties": {
          "hardCount": {
            "type": "integer",
            "format": "int32"
          },
          "softCount": {
            "type": "integer",
            "format": "int32"
          },
          "unknownCount": {
            "type": "integer",
            "description": "Bounces with no type signal. `hardCount + softCount + unknownCount` is every categorized bounce.",
            "format": "int32"
          },
          "byReason": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Counts keyed by reason, for example `invalidRecipient` or `policyBlocked`. Only non-zero reasons.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignPerformanceMetricsModel": {
        "type": "object",
        "properties": {
          "sentCount": {
            "type": "integer",
            "format": "int32"
          },
          "deliveredCount": {
            "type": "integer",
            "format": "int32"
          },
          "bounceCount": {
            "type": "integer",
            "format": "int32"
          },
          "openCount": {
            "type": "integer",
            "format": "int32"
          },
          "uniqueOpenCount": {
            "type": "integer",
            "format": "int32"
          },
          "clickCount": {
            "type": "integer",
            "format": "int32"
          },
          "uniqueClickCount": {
            "type": "integer",
            "format": "int32"
          },
          "botClickCount": {
            "type": "integer",
            "description": "Bot and scanner clicks. Not part of `clickCount` or `clickRate`.",
            "format": "int32"
          },
          "machineOpenCount": {
            "type": "integer",
            "description": "Contacts whose every open in the window was a machine open: Apple Mail Privacy Protection, a crawler, or an open within\na minute of the send (Gmail and security-scanner prefetch). Not part of `openCount`, `uniqueOpenCount` or\n`openRate`, which count human opens. Present on the email window metrics and step rows; omitted on day, segment and\ncampaign rows and on the linkedin channel. Opens are an estimate, never the headline: image blocking hides some and\nmachine opens are only those Kenso can tell apart.",
            "format": "int32",
            "nullable": true
          },
          "replyCount": {
            "type": "integer",
            "format": "int32"
          },
          "unsubscribeCount": {
            "type": "integer",
            "format": "int32"
          },
          "interestedCount": {
            "type": "integer",
            "format": "int32"
          },
          "contactedCount": {
            "type": "integer",
            "format": "int32"
          },
          "inviteCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "acceptedCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "messageCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "deliveryRate": {
            "type": "number",
            "format": "double"
          },
          "openRate": {
            "type": "number",
            "format": "double"
          },
          "clickRate": {
            "type": "number",
            "format": "double"
          },
          "replyRate": {
            "type": "number",
            "format": "double"
          },
          "bounceRate": {
            "type": "number",
            "format": "double"
          },
          "bounceBreakdown": {
            "$ref": "#/components/schemas/CampaignPerformanceBounceBreakdownModel"
          },
          "opportunitiesCreated": {
            "type": "integer",
            "description": "Opportunities created in the window from this campaign (or any campaign when none is set), by the\nopportunity's created_at day. Present on day and step rows and on the window metrics; omitted on\nsegment rows and on the linkedin channel. This and the three amount fields below are omitted unless the\n`opportunities` feature is on and the caller has accounts view.",
            "format": "int32",
            "nullable": true
          },
          "pipelineAmount": {
            "type": "number",
            "description": "Open amount of those opportunities now, in the workspace currency.",
            "format": "double",
            "nullable": true
          },
          "wonAmount": {
            "type": "number",
            "description": "Won amount of those opportunities now.",
            "format": "double",
            "nullable": true
          },
          "wonCount": {
            "type": "integer",
            "description": "How many of those opportunities are won now.",
            "format": "int32",
            "nullable": true
          },
          "meetingsBooked": {
            "type": "integer",
            "description": "Meetings booked from this campaign (or any campaign), by UTC day and step (DEV-1964). Omitted on segment rows and linkedin.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignPerformanceModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "timeZone": {
            "type": "string",
            "nullable": true
          },
          "groupBy": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "metrics": {
            "$ref": "#/components/schemas/CampaignPerformanceMetricsModel"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignPerformanceRowModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignPerformanceRowModel": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "date": {
            "type": "string",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "`groupBy=campaign` rows only: the campaign the row counts.",
            "format": "int64",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "routeKey": {
            "type": "string",
            "description": "`groupBy=sender_route` rows only, equal to `key`: the sender rule's provider slug, `everyone_else` or\n            `not_routed`.",
            "nullable": true
          },
          "metrics": {
            "$ref": "#/components/schemas/CampaignPerformanceMetricsModel"
          },
          "variants": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignPerformanceVariantModel"
            },
            "description": "LinkedIn step rows only: one entry per version (a to d), for the A/B and note vs no-note test.",
            "nullable": true
          },
          "notesWaiting": {
            "type": "integer",
            "description": "LinkedIn step rows only: AI notes requested or waiting for approval.",
            "format": "int32",
            "nullable": true
          },
          "notesSkippedFreeAccount": {
            "type": "integer",
            "description": "LinkedIn step rows only: invites sent without a note because the seat is not Premium.",
            "format": "int32",
            "nullable": true
          },
          "notesFailed": {
            "type": "integer",
            "description": "LinkedIn step rows only: notes that failed to generate.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignPerformanceVariantModel": {
        "type": "object",
        "properties": {
          "variant": {
            "type": "string",
            "nullable": true
          },
          "sentCount": {
            "type": "integer",
            "format": "int32"
          },
          "acceptedCount": {
            "type": "integer",
            "format": "int32"
          },
          "replyCount": {
            "type": "integer",
            "format": "int32"
          },
          "failedCount": {
            "type": "integer",
            "format": "int32"
          },
          "acceptRate": {
            "type": "number",
            "description": "acceptedCount / sentCount as a fraction from 0 to 1; 0 when nothing was sent.",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "CampaignPixelHostModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`link`: `link.{domain}` serves. `unsub`: the domain is on a Kenso Cloudflare zone, where Kenso creates\n            `unsub.{domain}` itself. `none`: no host on the domain and none Kenso can create, so campaign mail from it\n            goes out without a pixel; Ken.Scraper.API.Canonical.CampaignPixelHostModel.RequiredRecord names the record it needs. `unknown`: Kenso has not\n            tried a host there yet (a domain with no inbox, or the workspace's website domain), or is still trying.",
            "nullable": true
          },
          "hostname": {
            "type": "string",
            "description": "The pixel host for `link` and `unsub`, else omitted. For `unsub` it is the host Kenso creates, not\none confirmed to serve yet.",
            "nullable": true
          },
          "requiredRecord": {
            "$ref": "#/components/schemas/DomainDnsRecordModel"
          }
        },
        "additionalProperties": false
      },
      "CampaignSegmentFilterCriteriaDTO": {
        "type": "object",
        "properties": {
          "fullName": {
            "$ref": "#/components/schemas/StringFilter"
          },
          "titles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeTitles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "lastJobTitle": {
            "$ref": "#/components/schemas/StringFilter"
          },
          "headlines": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeHeadlines": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "summaryContains": {
            "type": "string",
            "nullable": true
          },
          "seniorityLevels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeSeniorityLevels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "functions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeFunctions": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "employmentTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "isDecisionMaker": {
            "type": "boolean",
            "nullable": true
          },
          "changedJobRecently": {
            "type": "boolean",
            "nullable": true
          },
          "yearsOfExperience": {
            "$ref": "#/components/schemas/FloatRange"
          },
          "yearsInCurrentRole": {
            "$ref": "#/components/schemas/FloatRange"
          },
          "yearsInCurrentCompany": {
            "$ref": "#/components/schemas/FloatRange"
          },
          "profileCountries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeProfileCountries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "profileState": {
            "type": "string",
            "nullable": true
          },
          "profileCity": {
            "type": "string",
            "nullable": true
          },
          "skillsContains": {
            "type": "string",
            "nullable": true
          },
          "certificationsContains": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "emailValidity": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "emailProviders": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeEmailProviders": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "isPersonalEmail": {
            "type": "boolean",
            "nullable": true
          },
          "hasLinkedInUrl": {
            "type": "boolean",
            "nullable": true
          },
          "hasPhone": {
            "type": "boolean",
            "nullable": true
          },
          "hasValidPhone": {
            "type": "boolean",
            "nullable": true
          },
          "companyNames": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeCompanyNames": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companyDomainContains": {
            "type": "string",
            "nullable": true
          },
          "companyDescriptionContains": {
            "type": "string",
            "nullable": true
          },
          "companySpecialitiesContains": {
            "type": "string",
            "nullable": true
          },
          "industries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeIndustries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companyHeadcount": {
            "$ref": "#/components/schemas/IntRange"
          },
          "companyFollowers": {
            "$ref": "#/components/schemas/IntRange"
          },
          "companyFoundedYear": {
            "$ref": "#/components/schemas/IntRange"
          },
          "companyTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "lastFundingRounds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "totalFunding": {
            "$ref": "#/components/schemas/LongRange"
          },
          "technologies": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeTechnologies": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companyHqCountries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "excludeCompanyHqCountries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companyHqState": {
            "type": "string",
            "nullable": true
          },
          "companyHqCity": {
            "type": "string",
            "nullable": true
          },
          "doNotContact": {
            "type": "boolean",
            "nullable": true
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateRange"
          },
          "totalClicks": {
            "$ref": "#/components/schemas/IntRange"
          },
          "leadQualityScore": {
            "$ref": "#/components/schemas/IntRange"
          },
          "aiVariableFilters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiVariableFilterDto"
            },
            "nullable": true
          },
          "customVariableFilters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomVariableFilterDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignSegmentFilterCriteriaSnapshot": {
        "type": "object",
        "properties": {
          "fullNameContains": {
            "type": "string",
            "nullable": true
          },
          "fullNameNotContains": {
            "type": "string",
            "nullable": true
          },
          "lastJobTitleContains": {
            "type": "string",
            "nullable": true
          },
          "lastJobTitleNotContains": {
            "type": "string",
            "nullable": true
          },
          "summaryContains": {
            "type": "string",
            "nullable": true
          },
          "profileStateContains": {
            "type": "string",
            "nullable": true
          },
          "profileCityContains": {
            "type": "string",
            "nullable": true
          },
          "skillsContains": {
            "type": "string",
            "nullable": true
          },
          "certificationsContains": {
            "type": "string",
            "nullable": true
          },
          "titles": {
            "type": "string",
            "nullable": true
          },
          "excludeTitles": {
            "type": "string",
            "nullable": true
          },
          "headlines": {
            "type": "string",
            "nullable": true
          },
          "excludeHeadlines": {
            "type": "string",
            "nullable": true
          },
          "seniorityLevels": {
            "type": "string",
            "nullable": true
          },
          "excludeSeniorityLevels": {
            "type": "string",
            "nullable": true
          },
          "functions": {
            "type": "string",
            "nullable": true
          },
          "excludeFunctions": {
            "type": "string",
            "nullable": true
          },
          "employmentTypes": {
            "type": "string",
            "nullable": true
          },
          "profileCountries": {
            "type": "string",
            "nullable": true
          },
          "excludeProfileCountries": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "string",
            "nullable": true
          },
          "emailValidity": {
            "type": "string",
            "nullable": true
          },
          "emailProviders": {
            "type": "string",
            "nullable": true
          },
          "excludeEmailProviders": {
            "type": "string",
            "nullable": true
          },
          "isDecisionMaker": {
            "type": "boolean",
            "nullable": true
          },
          "changedJobRecently": {
            "type": "boolean",
            "nullable": true
          },
          "isPersonalEmail": {
            "type": "boolean",
            "nullable": true
          },
          "hasLinkedInUrl": {
            "type": "boolean",
            "nullable": true
          },
          "hasPhone": {
            "type": "boolean",
            "nullable": true
          },
          "hasValidPhone": {
            "type": "boolean",
            "nullable": true
          },
          "yearsOfExperienceMin": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "yearsOfExperienceMax": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "yearsInCurrentRoleMin": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "yearsInCurrentRoleMax": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "yearsInCurrentCompanyMin": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "yearsInCurrentCompanyMax": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "companyDomainContains": {
            "type": "string",
            "nullable": true
          },
          "companyDescriptionContains": {
            "type": "string",
            "nullable": true
          },
          "companySpecialitiesContains": {
            "type": "string",
            "nullable": true
          },
          "companyHqStateContains": {
            "type": "string",
            "nullable": true
          },
          "companyHqCityContains": {
            "type": "string",
            "nullable": true
          },
          "companyNames": {
            "type": "string",
            "nullable": true
          },
          "excludeCompanyNames": {
            "type": "string",
            "nullable": true
          },
          "industries": {
            "type": "string",
            "nullable": true
          },
          "excludeIndustries": {
            "type": "string",
            "nullable": true
          },
          "companyTypes": {
            "type": "string",
            "nullable": true
          },
          "lastFundingRounds": {
            "type": "string",
            "nullable": true
          },
          "technologies": {
            "type": "string",
            "nullable": true
          },
          "excludeTechnologies": {
            "type": "string",
            "nullable": true
          },
          "companyHqCountries": {
            "type": "string",
            "nullable": true
          },
          "excludeCompanyHqCountries": {
            "type": "string",
            "nullable": true
          },
          "companyHeadcountMin": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyHeadcountMax": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyFollowersMin": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyFollowersMax": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyFoundedYearMin": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyFoundedYearMax": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "totalFundingMin": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "totalFundingMax": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "doNotContact": {
            "type": "boolean",
            "nullable": true
          },
          "createdFrom": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdTo": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "totalClicksMin": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "totalClicksMax": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "leadQualityScoreMin": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "leadQualityScoreMax": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "aiVariableFiltersJson": {
            "type": "string",
            "nullable": true
          },
          "customVariableFiltersJson": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignWeeklyReportChangeModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "`sequence_version_saved`, `linkedin_sequence_version_saved`, `variant_paused`,\n            `variant_resumed`, `segment_added`, or `leads_held_back` (one line with the week's\n            leads stopped for 1:1 account plays, dated by the last stop). Tolerate values not listed here.",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "segmentId": {
            "type": "integer",
            "description": "The segment the change belongs to, when it belongs to one.",
            "format": "int64",
            "nullable": true
          },
          "text": {
            "type": "string",
            "description": "One plain-English sentence, dated by the change's UTC day.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignWeeklyReportMetricsModel": {
        "type": "object",
        "properties": {
          "startDate": {
            "type": "string",
            "description": "First day of the window, `YYYY-MM-DD`.",
            "nullable": true
          },
          "endDate": {
            "type": "string",
            "description": "Last day of the window (inclusive), `YYYY-MM-DD`.",
            "nullable": true
          },
          "sentCount": {
            "type": "integer",
            "description": "Emails sent.",
            "format": "int32"
          },
          "contactedCount": {
            "type": "integer",
            "description": "Distinct people emailed.",
            "format": "int32"
          },
          "replyCount": {
            "type": "integer",
            "description": "Distinct people who replied.",
            "format": "int32"
          },
          "interestedCount": {
            "type": "integer",
            "description": "Distinct people whose reply is classified interested (positive replies).",
            "format": "int32"
          },
          "bounceCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CampaignWeeklyReportModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "timeZone": {
            "type": "string",
            "description": "IANA zone the week's dates are picked in, or `UTC`.",
            "nullable": true
          },
          "week": {
            "$ref": "#/components/schemas/CampaignWeeklyReportMetricsModel"
          },
          "toDate": {
            "$ref": "#/components/schemas/CampaignWeeklyReportMetricsModel"
          },
          "segments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignWeeklyReportSegmentModel"
            },
            "description": "Per segment, to date.",
            "nullable": true
          },
          "changed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignWeeklyReportChangeModel"
            },
            "description": "What changed during the week, newest first, at most 6.",
            "nullable": true
          },
          "next": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignWeeklyReportNextStepModel"
            },
            "description": "What happens next, as of the request. Empty for a week older than the default week.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One campaign's weekly report. Text is built from data, not AI."
      },
      "CampaignWeeklyReportNextStepModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "`campaign_remaining` (one line), then `segment_remaining` per segment with leads not\n            started; or a single `campaign_paused`, `campaign_error`, `campaign_completed`,\n            or `campaign_archived` line. Tolerate values not listed here.",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "description": "On `segment_remaining`.",
            "format": "int64",
            "nullable": true
          },
          "remainingCount": {
            "type": "integer",
            "description": "Leads not started yet: in the campaign on `campaign_remaining`, in the segment on `segment_remaining`.",
            "format": "int32",
            "nullable": true
          },
          "finishDate": {
            "type": "string",
            "description": "On `campaign_remaining`: the day the last lead starts at the last 7 days' pace,\n`YYYY-MM-DD`, when one can be estimated.",
            "nullable": true
          },
          "text": {
            "type": "string",
            "description": "One plain-English sentence.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CampaignWeeklyReportSegmentModel": {
        "type": "object",
        "properties": {
          "segmentId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "contactCount": {
            "type": "integer",
            "description": "Contacts in the segment now.",
            "format": "int32"
          },
          "sentCount": {
            "type": "integer",
            "description": "Emails sent to date.",
            "format": "int32"
          },
          "replyRate": {
            "type": "number",
            "description": "Fraction from 0 to 1, as on the campaign performance segment rows.",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "CanonicalErrorAccount": {
        "type": "object",
        "properties": {
          "accountId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "stakeholderId": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false,
        "description": "One account a person sits on, named in an error detail."
      },
      "CanonicalErrorBody": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "details": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CanonicalErrorDetail"
            },
            "nullable": true
          },
          "requestId": {
            "type": "string",
            "nullable": true
          },
          "refusal": {
            "$ref": "#/components/schemas/RefusalDto"
          },
          "impact": {
            "$ref": "#/components/schemas/CanonicalInvalidationImpact"
          }
        },
        "additionalProperties": false
      },
      "CanonicalErrorDetail": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "nullable": true
          },
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "description": "Matching rows on `export_limit_exceeded`. Omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "index": {
            "type": "integer",
            "description": "Position of the refused item in the request's list (demo director `invalid_change`). Omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "description": "Row limit the export ran with on `export_limit_exceeded`; the policy's limit on a `quota_exceeded`\ndetail whose `field` names the policy. Omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "resetAt": {
            "type": "string",
            "description": "When the breached window frees up, in UTC, on a handler's `quota_exceeded` detail that names its policy (the\noutbound-site refresh): the same instant as the top-level `quotaResetAt`. Omitted otherwise.",
            "format": "date-time",
            "nullable": true
          },
          "retryAfterSeconds": {
            "type": "integer",
            "description": "Seconds to wait on that `quota_exceeded` detail: the same value as the `Retry-After` header. Omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "description": "Inbox the reason is about (SMTP pool convert rejections). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "description": "Domain the reason is about (SMTP pool convert rejections). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "description": "Name of Ken.Scraper.API.Canonical.CanonicalErrorDetail.DomainId, or the domain name the request gave. Omitted otherwise.",
            "nullable": true
          },
          "accountId": {
            "type": "integer",
            "description": "The account to use instead (Accounts: domain_taken, already_stakeholder, previously_removed). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "personId": {
            "type": "integer",
            "description": "The person to use instead (Accounts: email_taken, linkedin_url_taken). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "stakeholderId": {
            "type": "integer",
            "description": "The stakeholder the reason is about (Accounts). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "championId": {
            "type": "integer",
            "description": "Always omitted: its only error, already_champion, went with /v1/champions (DEV-4284). Kept so the error shape does not change.",
            "format": "int64",
            "nullable": true
          },
          "callTaskId": {
            "type": "integer",
            "description": "The open call task that already holds the person's slot (call_task_exists, DEV-3365). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "Current status on invalid_transition. Omitted otherwise.",
            "nullable": true
          },
          "allowed": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Allowed values (out_of_range) or allowed source statuses (invalid_transition). Omitted otherwise.",
            "nullable": true
          },
          "scope": {
            "type": "string",
            "description": "The account scope a `permission_denied` needs (`all`, Accounts owner changes), or what a\n`sending_paused` pause covers (`inbox`, `domain` or `workspace`, agent sends). Omitted otherwise.",
            "nullable": true
          },
          "removedAt": {
            "type": "string",
            "description": "When a person removed the stakeholder (previously_removed). Omitted otherwise.",
            "format": "date-time",
            "nullable": true
          },
          "page": {
            "type": "string",
            "description": "The page a `permission_denied` needs (wire name, e.g. `campaigns`). Omitted otherwise.",
            "nullable": true
          },
          "required": {
            "type": "string",
            "description": "The level Ken.Scraper.API.Canonical.CanonicalErrorDetail.Page needs on `permission_denied` (`view` or `edit`). Omitted otherwise.",
            "nullable": true
          },
          "feature": {
            "type": "string",
            "description": "The feature a `permission_denied` needs (wire name, e.g. `launch`). Omitted otherwise.",
            "nullable": true
          },
          "runId": {
            "type": "integer",
            "description": "The committee run the reason is about (Accounts: committee_run_active, run_not_finding). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "mergedIntoId": {
            "type": "integer",
            "description": "The live record a merged id now lives on as (Accounts: person_merged names the kept person, account_merged the live account). Omitted otherwise.",
            "format": "int64",
            "nullable": true
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CanonicalErrorAccount"
            },
            "description": "The live accounts that block the change (Accounts: person_on_accounts). Omitted otherwise.",
            "nullable": true
          },
          "stage": {
            "type": "string",
            "description": "The opportunity stage key the reason is about (Opportunities: stage_in_use, system_stage). Omitted otherwise.",
            "nullable": true
          },
          "opportunityCount": {
            "type": "integer",
            "description": "Live opportunities in that stage (Opportunities: stage_in_use). Omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "rule": {
            "type": "string",
            "description": "The broken Contact limits rule on `guardrail_violation` (DEV-1762). Omitted otherwise.",
            "nullable": true
          },
          "nextAllowedAt": {
            "type": "string",
            "description": "The first dueAt that passes every guardrail on `guardrail_violation`; when to retry on an agent or\nAPI-key send refusal (DEV-3672). Omitted otherwise, and when no dueAt in the next 180 days passes.",
            "format": "date-time",
            "nullable": true
          },
          "fix": {
            "type": "string",
            "description": "What the caller does next, in plain words (DEV-3672 agent and API-key send refusals). Omitted otherwise.",
            "nullable": true
          },
          "opensAt": {
            "type": "string",
            "description": "When the person's calling window opens (calls: outside_calling_hours). Omitted otherwise.",
            "format": "date-time",
            "nullable": true
          },
          "currentVersion": {
            "type": "integer",
            "description": "The file's current version (Knowledge: version_conflict). Omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "description": "The CRM a CRM OAuth failure is about (provider_error, exchange_failed, plan_required, already_connected,\naccount_mismatch, provider_unavailable). Omitted otherwise.",
            "nullable": true
          },
          "sharedWithMaster": {
            "type": "boolean",
            "description": "True on a `quota_exceeded` detail when the white-label master's shared cap was hit (DEV-3688), so\nKen.Scraper.API.Canonical.CanonicalErrorDetail.Limit is the whole white-label account's. Omitted otherwise. The master's id is never sent.",
            "nullable": true
          },
          "stepId": {
            "type": "integer",
            "description": "The saved sequence step a `link_reputation_blocked` detail is about. Omitted otherwise, and for a step the\nsave would have created.",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "description": "The `stepOrder` of the step a `link_reputation_blocked` detail is about. Omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "The refused link on a `link_reputation_blocked` detail, as the step's own copy writes it (DEV-5274), the\nlegacy `blockedLinks[].url`. Omitted otherwise.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CanonicalFailure": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "error": {
            "$ref": "#/components/schemas/CanonicalErrorBody"
          },
          "quotaResetAt": {
            "type": "string",
            "description": "Top-level instant on a support-turn, AI assist or outbound-site refresh quota refusal. Same value\nas the legacy `quotaResetAt`. Omitted when null.",
            "format": "date-time",
            "nullable": true
          },
          "currentVersion": {
            "type": "integer",
            "description": "Top-level current draft revision on a workflow draft save's `409 version_conflict`: read the\nworkflow again and send this as `baseVersion`. Omitted when null.",
            "format": "int32",
            "nullable": true
          },
          "current": {
            "$ref": "#/components/schemas/MeetingRepNotesCurrentModel"
          },
          "refusal": {
            "$ref": "#/components/schemas/RefusalDto"
          },
          "message": {
            "type": "string",
            "description": "Top-level copy of `error.message`, set together with Ken.Scraper.API.Canonical.CanonicalFailure.Refusal. Omitted when null.",
            "nullable": true
          },
          "lookalikeSeeds": {
            "description": "Ken Search's seed report on a lookalike search's `422 no_usable_seeds` (DEV-6968):\n`{resolved: [{input, companyId, personId, name, domain}], unresolved: [{input, reason}]}`, so the caller can\nshow why no seed was usable. Omitted otherwise.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Wire shape for a canonical failure. Legacy `BaseResponse` stays on unconstrained actions."
      },
      "CanonicalInvalidationImpact": {
        "type": "object",
        "properties": {
          "qualificationResponses": {
            "type": "integer",
            "format": "int32"
          },
          "qualifiedFlags": {
            "type": "integer",
            "format": "int32"
          },
          "segmentationReasoning": {
            "type": "integer",
            "format": "int32"
          },
          "segmentationAssignmentsKept": {
            "type": "integer",
            "format": "int32"
          },
          "segmentationAssignmentsReset": {
            "type": "integer",
            "format": "int32"
          },
          "personalizationLines": {
            "type": "integer",
            "format": "int32"
          },
          "personalizationLeads": {
            "type": "integer",
            "format": "int32"
          },
          "rewritingLines": {
            "type": "integer",
            "format": "int32"
          },
          "rewritingLeads": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Wire counts for an AI-flow wipe. Matches `AiFlowInvalidationImpactDto` without its enums."
      },
      "CanonicalListResponseOfAccessRequestModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccessRequestModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfAgentProposalModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AgentProposalModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfAiLineHoldModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AiLineHoldModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfAutoPauseModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AutoPauseModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfAvailableCallingNumberModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AvailableCallingNumberModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfBlocklistRuleModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BlocklistRuleModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfBookingLinkSummaryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BookingLinkSummaryModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfBookingModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BookingModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCallingNumberModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CallingNumberModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCallingVoicemailModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CallingVoicemailModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCampaignAiWorkflowModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignAiWorkflowModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCampaignImageModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignImageModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCampaignListModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignListModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCampaignLocalizationModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignLocalizationModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCampaignModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfClientApprovalEventModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientApprovalEventModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfClientApprovalItemModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientApprovalItemModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCompanyModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompanyModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfContactAiLineModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactAiLineModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfContactEventModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactEventModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfContactFieldModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactFieldModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfContactModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfContactWebsitePageModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactWebsitePageModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCreditLedgerEntryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditLedgerEntryModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCreditSavingsRowModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditSavingsRowModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCrmConnectionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmConnectionModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCrmFieldModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmFieldModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCrmListModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmListModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCrmPipelineModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmPipelineModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCrmRecordModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmRecordModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCrmSyncIssueModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmSyncIssueModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfCustomVariableModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CustomVariableModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfDomainModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfEventModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfEventSubscriptionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventSubscriptionModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfExternalBookingModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ExternalBookingModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfInboundWebhookDeliveryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboundWebhookDeliveryModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfInboundWebhookModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboundWebhookModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfInboxModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboxModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfInfraFindingModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InfraFindingModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfJobModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JobModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfLinkedInAccountModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LinkedInAccountModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfLinkedInEngagementModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LinkedInEngagementModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfMarketSummaryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketSummaryModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfMeetingTypeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingTypeModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfOutboundSiteVersionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OutboundSiteVersionModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfPermissionTemplateModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PermissionTemplateModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfPlacementTestModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlacementTestModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfPromptModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfPromptVersionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptVersionModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfReplyTemplateModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplyTemplateModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfSavedListGrantModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedListGrantModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfSavedListMemberModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedListMemberModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfSavedListModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedListModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfSegmentModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SegmentModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfSegmentVersionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SegmentVersionModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfSequenceVersionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceVersionModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfTagModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfThreadMessageModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadMessageModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfThreadModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfTrackingLinkModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TrackingLinkModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfTriggerFiringModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TriggerFiringModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfTriggerModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TriggerModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfTriggerSchemaModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TriggerSchemaModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfWebhookDeliveryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookDeliveryModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfWebhookEndpointModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEndpointModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfWebhookEventTypeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookEventTypeModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalListResponseOfWorkspaceSummaryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkspaceSummaryModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          }
        },
        "additionalProperties": false
      },
      "CanonicalPagination": {
        "type": "object",
        "properties": {
          "nextCursor": {
            "type": "string",
            "nullable": true
          },
          "hasMore": {
            "type": "boolean"
          },
          "total": {
            "type": "integer",
            "description": "Full match count when the list is filtered before paging. Omitted when unknown.",
            "format": "int32",
            "nullable": true
          },
          "isTotalCapped": {
            "type": "boolean",
            "description": "True when Ken.Scraper.API.Canonical.CanonicalPagination.Total stopped counting at its cap, so more items match than it says; page on with\nKen.Scraper.API.Canonical.CanonicalPagination.HasMore. Omitted when the total is exact. Only `GET /v1/threads` with `q` caps (DEV-4517).",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CanonicalResourceResponseOfAccessRequestModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AccessRequestModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAgentActionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AgentActionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAgentActionOutcomeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AgentActionOutcomeModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAgentProposalModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AgentProposalModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAgentTeamChangesModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AgentTeamChangesModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAiLineHoldApprovalModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AiLineHoldApprovalModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAiRunDryRunModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AiRunDryRunModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAiRunEligibilityModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AiRunEligibilityModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAiRunModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AiRunModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAiRunResetModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AiRunResetModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAnalyticsQueryResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AnalyticsQueryResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAttachmentModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AttachmentModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfAutonomousReplySettingsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/AutonomousReplySettingsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBlocklistBulkDeleteResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BlocklistBulkDeleteResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBlocklistBulkResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BlocklistBulkResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBlocklistEntryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BlocklistEntryModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBlocklistImportModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BlocklistImportModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBlocklistRuleModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BlocklistRuleModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBlocklistRulePreviewModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BlocklistRulePreviewModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBookingLeaverResultModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BookingLeaverResultModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBookingLinkModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BookingLinkModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBookingLinkSummaryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BookingLinkSummaryModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBookingModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BookingModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBrandByHostModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BrandByHostModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBugReportReceiptModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BugReportReceiptModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfBuyerPreviewModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/BuyerPreviewModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingCallModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingCallModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingHangupModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingHangupModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingNumberModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingNumberModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingRateModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingRateModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingSettingsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingSettingsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingSpendLimitModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingSpendLimitModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingTokenModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingTokenModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingVoicemailDropModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingVoicemailDropModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCallingVoicemailModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CallingVoicemailModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignComplianceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignComplianceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignImageModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignImageModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignLanguagesModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignLanguagesModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignListModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignListModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignLocalizationModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignLocalizationModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignMailProvidersModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignMailProvidersModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignPerformanceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignPerformanceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCampaignWeeklyReportModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CampaignWeeklyReportModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCliLoginCreatedModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CliLoginCreatedModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCliLoginTokenModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CliLoginTokenModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfClientApprovalItemDetailModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ClientApprovalItemDetailModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfClientApprovalSettingsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ClientApprovalSettingsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCompanyDataModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CompanyDataModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCompanyModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CompanyModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfContactAiLineModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ContactAiLineModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfContactBulkRestoreResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ContactBulkRestoreResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfContactBulkResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ContactBulkResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfContactBulkUpdateResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ContactBulkUpdateResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfContactImportScanModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ContactImportScanModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfContactModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ContactModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCreditBalanceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CreditBalanceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCreditEstimateModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CreditEstimateModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCreditRateCardModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CreditRateCardModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCreditSavingsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CreditSavingsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCreditSpendModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CreditSpendModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCrmAuthorizeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CrmAuthorizeModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCrmConnectionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CrmConnectionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCrmFieldMapModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CrmFieldMapModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCrmImportModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CrmImportModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCrmOAuthCompletionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CrmOAuthCompletionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCrmPreviewModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CrmPreviewModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCrmSyncHealthModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CrmSyncHealthModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfCustomVariableModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/CustomVariableModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDeliverabilityGatesModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DeliverabilityGatesModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDeliverabilityModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DeliverabilityModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDomainBulkResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DomainBulkResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDomainDnsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DomainDnsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDomainHealthModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DomainHealthModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDomainModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DomainModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDomainNameserverCheckModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DomainNameserverCheckModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfDomainWebsiteModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/DomainWebsiteModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailCopyGradeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailCopyGradeModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailCopyLintModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailCopyLintModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailFindModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailFindModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailSequenceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailSequenceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailSequencePreviewModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailSequencePreviewModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailSequenceTestSendModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailSequenceTestSendModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailSequenceVersionDetailModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailSequenceVersionDetailModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEmailSequenceVersionSaveModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EmailSequenceVersionSaveModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEngagementModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EngagementModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEventCountsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EventCountsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEventOccurrencesModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EventOccurrencesModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEventSubscriptionGrantModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EventSubscriptionGrantModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfEventSubscriptionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/EventSubscriptionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfExternalBookingModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ExternalBookingModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfFundingRoundsExportAllowanceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/FundingRoundsExportAllowanceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfIReadOnlyListOfSavedListSourceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedListSourceModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfImageVariableEstimateModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ImageVariableEstimateModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfImageVariableModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ImageVariableModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfImageVariableTestModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ImageVariableTestModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInboundWebhookMappingTestModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InboundWebhookMappingTestModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInboundWebhookModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InboundWebhookModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInboxBulkResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InboxBulkResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInboxConnectSessionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InboxConnectSessionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInboxModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InboxModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInboxRenameModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InboxRenameModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInboxWarmupModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InboxWarmupModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInfraFindingModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InfraFindingModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfInfraSummaryModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/InfraSummaryModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfJobModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/JobModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfJobPostSearchImportResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/JobPostSearchImportResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfJobPostingsExportAllowanceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/JobPostingsExportAllowanceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfJsonElement": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": { }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfLaunchReadinessModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LaunchReadinessModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfLinkedInAccountModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LinkedInAccountModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfLinkedInConnectSessionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LinkedInConnectSessionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfLinkedInSequenceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LinkedInSequenceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfLinkedInSequenceVersionDetailModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LinkedInSequenceVersionDetailModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfLinkedInSequenceVersionSaveModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LinkedInSequenceVersionSaveModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfLinkedInSettingsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/LinkedInSettingsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfMarkAllThreadsReadModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MarkAllThreadsReadModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfMarketModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MarketModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfMeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MeModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfMeetingClientBriefModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MeetingClientBriefModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfMeetingTypeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MeetingTypeModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfMeetingTypeSlotsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MeetingTypeSlotsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfMemberPermissionsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/MemberPermissionsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfOutboundSiteModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/OutboundSiteModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfOutboundSitePreviewLink": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/OutboundSitePreviewLink"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfOutboundSiteRunModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/OutboundSiteRunModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfPermissionTemplateModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PermissionTemplateModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfPersonIntakeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PersonIntakeModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfPlacementTestModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PlacementTestModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfPromptModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PromptModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfPromptTestResultModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PromptTestResultModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfPromptVersionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PromptVersionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfPromptVersionRestoreModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/PromptVersionRestoreModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfRecipientProviderCountsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/RecipientProviderCountsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfReplyClassificationsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ReplyClassificationsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfReplyTemplateModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ReplyTemplateModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfRetryEnrichmentModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/RetryEnrichmentModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfRunwayModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/RunwayModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSavedListGrantModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SavedListGrantModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSavedListInviteModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SavedListInviteModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSavedListModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SavedListModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSavedListRightsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SavedListRightsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSavedListSourceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SavedListSourceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSavedListSubmissionModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SavedListSubmissionModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfScheduledMessageModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ScheduledMessageModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfScoringSettingsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ScoringSettingsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSearchImportPreview": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SearchImportPreview"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSearchSampleResource": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SearchSampleResource"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSegmentFilterMetadataDTO": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SegmentFilterMetadataDTO"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSegmentModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SegmentModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSegmentPreviewModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SegmentPreviewModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSegmentRestoreModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SegmentRestoreModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSegmentVersionDetailModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SegmentVersionDetailModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSegmentVersionSaveModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SegmentVersionSaveModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSenderRoutingModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SenderRoutingModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSendingCapacityForecastModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SendingCapacityForecastModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSequenceRestoreModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SequenceRestoreModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSequenceVariablesModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SequenceVariablesModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfShareModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ShareModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSharePublicModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SharePublicModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfShareReminderModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ShareReminderModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSignalIntakeModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SignalIntakeModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfSuggestedTimesModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/SuggestedTimesModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTagAssignmentBulkResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TagAssignmentBulkResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTagAssignmentModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TagAssignmentModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTagModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TagModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfThreadBulkResult": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ThreadBulkResult"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfThreadCountsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ThreadCountsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfThreadDraftModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ThreadDraftModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfThreadMessageAwaitingApprovalModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ThreadMessageAwaitingApprovalModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfThreadMessageHeldModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ThreadMessageHeldModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfThreadMessageModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ThreadMessageModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfThreadModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/ThreadModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTrackingLinkModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TrackingLinkModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTranslationModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TranslationModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTriggerModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TriggerModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTriggerStatsModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TriggerStatsModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfTriggerTestFireModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/TriggerTestFireModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfWebhookDeliveryResendModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WebhookDeliveryResendModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfWebhookEndpointModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WebhookEndpointModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfWebhookEndpointTestModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WebhookEndpointTestModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfWebhookRecoverModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WebhookRecoverModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfWebhookSigningSecretModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WebhookSigningSecretModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfWorkflowReadinessModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WorkflowReadinessModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CanonicalResourceResponseOfWorkspaceModel": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "$ref": "#/components/schemas/WorkspaceModel"
          }
        },
        "additionalProperties": false,
        "description": "Single-resource success envelope. Lists use Ken.Scraper.API.Canonical.CanonicalListResponse`1."
      },
      "CliLoginCreatedModel": {
        "type": "object",
        "properties": {
          "loginId": {
            "type": "string",
            "description": "The CLI's pickup credential for `POST /v1/cli/logins/token`. Keep it private.",
            "nullable": true
          },
          "userCode": {
            "type": "string",
            "description": "`XXXX-XXXX`: the code the person confirms in the browser.",
            "nullable": true
          },
          "verificationUrl": {
            "type": "string",
            "description": "The approval page with the code filled in.",
            "nullable": true
          },
          "expiresIn": {
            "type": "integer",
            "description": "Seconds until the login expires.",
            "format": "int32"
          },
          "interval": {
            "type": "integer",
            "description": "Seconds to wait between polls.",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CliLoginTokenModel": {
        "type": "object",
        "properties": {
          "apiKey": {
            "type": "string",
            "description": "The new Kenso API key (`ken_`...). Returned once.",
            "nullable": true
          },
          "apiKeyId": {
            "type": "string",
            "description": "Its id, as `GET /v1/api-keys` lists it.",
            "nullable": true
          },
          "workspaceId": {
            "type": "integer",
            "description": "The workspace the person picked: the CLI profile's default.",
            "format": "int64"
          },
          "email": {
            "type": "string",
            "description": "The approver's email, when their session carried one.",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "description": "When the key expires.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CliLoginTokenRequest": {
        "type": "object",
        "properties": {
          "loginId": {
            "type": "string",
            "description": "The `loginId` the create returned.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/cli/logins/token`."
      },
      "ClientApprovalCommentModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "anchor": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "authorName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A reviewer comment. `anchor` is the step, variant or paragraph key, or null for the whole item."
      },
      "ClientApprovalEventModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "itemId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "eventType": {
            "type": "string",
            "nullable": true
          },
          "actorKind": {
            "type": "string",
            "nullable": true
          },
          "actorName": {
            "type": "string",
            "nullable": true
          },
          "actorUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "data": {
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "One approval log entry. `actorKind`: reviewer, user, system."
      },
      "ClientApprovalItemDetailModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "subjectId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "subjectKey": {
            "type": "string",
            "nullable": true
          },
          "fingerprint": {
            "type": "string",
            "nullable": true
          },
          "pausedCampaign": {
            "type": "boolean"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "decidedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decidedByName": {
            "type": "string",
            "nullable": true
          },
          "decisionComment": {
            "type": "string",
            "nullable": true
          },
          "snapshot": { },
          "comments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientApprovalCommentModel"
            },
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ClientApprovalEventModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "`GET /v1/client-approvals/items/{itemId}`: the item, its snapshot as stored without the reply's internal\n            `send` block (M:Ken.Scraper.API.Canonical.ClientApprovalMapper.PartnerSnapshot(Ken.Scraping.Domain.Entities.ClientApprovalItem)), comments (oldest first) and log (newest first)."
      },
      "ClientApprovalItemModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "subjectId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "subjectKey": {
            "type": "string",
            "nullable": true
          },
          "fingerprint": {
            "type": "string",
            "nullable": true
          },
          "pausedCampaign": {
            "type": "boolean"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "decidedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decidedByName": {
            "type": "string",
            "nullable": true
          },
          "decisionComment": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "An external approval item as listed. `kind`: copy, lead_list, reply, order. `status`: pending, approved, changes_requested, superseded, cancelled."
      },
      "ClientApprovalRulesModel": {
        "type": "object",
        "properties": {
          "copy": {
            "type": "string",
            "nullable": true
          },
          "leadList": {
            "type": "string",
            "nullable": true
          },
          "reply": {
            "type": "string",
            "nullable": true
          },
          "order": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Per-kind rule: `require` or `auto`."
      },
      "ClientApprovalSettingsModel": {
        "type": "object",
        "properties": {
          "rules": {
            "$ref": "#/components/schemas/ClientApprovalRulesModel"
          },
          "reminderEmails": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "timeZone": {
            "type": "string",
            "nullable": true
          },
          "portalUrl": {
            "type": "string",
            "nullable": true
          },
          "portalTokenRotatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "approvalLinksEnabled": {
            "type": "boolean"
          },
          "pendingCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "`GET` / `PATCH /v1/client-approvals/settings` and `POST .../rotate-link`.\n            `portalUrl` is the no-login link for the partner's client. `approvalLinksEnabled` is the\n            effective switch, read from the white-label master."
      },
      "CompanyBrandModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "description": "The company's logo image, an absolute http(s) URL.",
            "nullable": true
          },
          "source": {
            "type": "string",
            "description": "Where the data came from: ken_search.",
            "nullable": true
          },
          "fetchedAt": {
            "type": "string",
            "description": "When Kenso read the data from its source.",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CompanyDataModel": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "description": "The registrable domain looked up (acme.com for https://www.eu.acme.com/x).",
            "nullable": true
          },
          "isCompanyFound": {
            "type": "boolean",
            "description": "True when Kenso Search's company index has the domain's company (what brand and funding read). Absent when neither\nbrand nor funding was asked for, because the index was not read.",
            "nullable": true
          },
          "brand": {
            "$ref": "#/components/schemas/CompanyBrandModel"
          },
          "technologies": {
            "$ref": "#/components/schemas/CompanyTechnologiesModel"
          },
          "funding": {
            "$ref": "#/components/schemas/CompanyFundingModel"
          }
        },
        "additionalProperties": false,
        "description": "One domain's company data. A kind is absent when it was not asked for or Kenso has nothing for it."
      },
      "CompanyFundingModel": {
        "type": "object",
        "properties": {
          "totalFunding": {
            "$ref": "#/components/schemas/MoneyModel"
          },
          "lastRound": {
            "$ref": "#/components/schemas/CompanyFundingRoundModel"
          },
          "rounds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompanyFundingRoundModel"
            },
            "description": "The rounds Kenso knows, newest first, at most 20.",
            "nullable": true
          },
          "source": {
            "type": "string",
            "description": "Where the data came from: ken_search.",
            "nullable": true
          },
          "fetchedAt": {
            "type": "string",
            "description": "When Kenso read the data from its source.",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CompanyFundingRoundModel": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "The round, e.g. Seed or Series B.",
            "nullable": true
          },
          "amount": {
            "$ref": "#/components/schemas/MoneyModel"
          },
          "announcedDate": {
            "type": "string",
            "description": "When the round was announced (YYYY-MM-DD).",
            "format": "date",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CompanyModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "domain": {
            "type": "string",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "industry": {
            "type": "string",
            "nullable": true
          },
          "employeeCount": {
            "type": "integer",
            "format": "int32"
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CompanyTechnologiesModel": {
        "type": "object",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CompanyTechnologyModel"
            },
            "description": "Technologies seen on the company's website, most recently seen first, at most 200. Empty when Kenso has a\n            capture of the site and detected none.",
            "nullable": true
          },
          "source": {
            "type": "string",
            "description": "Where the data came from: ken_search (its archive of HTTP Archive and Common Crawl captures).",
            "nullable": true
          },
          "capturedAt": {
            "type": "string",
            "description": "When the archived home page the technologies were detected on was captured.",
            "format": "date-time",
            "nullable": true
          },
          "fetchedAt": {
            "type": "string",
            "description": "When Kenso read the data from its source.",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CompanyTechnologyModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "The technology, e.g. HubSpot or Shopify.",
            "nullable": true
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Its categories, e.g. [\"Marketing automation\"]; often one, sometimes none.",
            "nullable": true
          },
          "lastSeenAt": {
            "type": "string",
            "description": "When Kenso last saw it on the company's website.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ComparisonOperatorEnum": {
        "enum": [
          0,
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14
        ],
        "type": "integer",
        "format": "int32"
      },
      "CompleteCrmOAuthBody": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "errorDescription": {
            "type": "string",
            "nullable": true
          },
          "accountsServer": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ConnectCrmBody": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "nullable": true
          },
          "apiKey": {
            "type": "string",
            "nullable": true
          },
          "baseUrl": {
            "type": "string",
            "nullable": true
          },
          "returnPath": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ConnectedViaModel": {
        "type": "object",
        "properties": {
          "linkedinAccountId": {
            "type": "integer",
            "format": "int64"
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "memberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ContactAccountPlayModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`skipped`: enforced, held before the campaign's first step (a contact that already got a step\n            is stopped at its next send). `stopped`: its sequence was stopped for good. `would_skip`:\n            shadow, sending unchanged.",
            "nullable": true
          },
          "accountId": {
            "type": "integer",
            "description": "The account play that matches now. Omitted on a stopped contact whose account left the active stages, and, with\naccount name and stage, for a caller with account scope own when it does not own that account (DEV-1654 spec 8.2).",
            "format": "int64",
            "nullable": true
          },
          "accountName": {
            "type": "string",
            "nullable": true
          },
          "accountStage": {
            "type": "string",
            "description": "`warming`, `engaged` or `meeting_booked`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-1520: a contact's account-play status in its campaign."
      },
      "ContactAiLineModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "The AI line id.",
            "format": "int64"
          },
          "promptId": {
            "type": "integer",
            "description": "The prompt that wrote the line.",
            "format": "int64"
          },
          "variable": {
            "type": "string",
            "description": "The template variable the line fills, the prompt's name (for example `first_line`).",
            "nullable": true
          },
          "text": {
            "type": "string",
            "description": "The line's text.",
            "nullable": true
          },
          "rewrite": {
            "type": "boolean",
            "description": "True when a rewriting prompt wrote the line from a personalized one."
          },
          "segmentId": {
            "type": "integer",
            "description": "The segment the line was written for. Omitted when the line is not segment-scoped.",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "description": "The sequence step the line was written for. Omitted when the line serves every step.",
            "format": "int32",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "description": "When the line was written.",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "One live AI line of a contact (DEV-4637): the text the next send renders for its variable and the approval page\nshows."
      },
      "ContactBulkError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ContactBulkFailure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "index": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "error": {
            "$ref": "#/components/schemas/ContactBulkError"
          }
        },
        "additionalProperties": false
      },
      "ContactBulkRestoreResult": {
        "type": "object",
        "properties": {
          "restored": {
            "type": "integer",
            "description": "How many contacts this call restored: the length of Ken.Scraper.API.Canonical.ContactBulkRestoreResult.Succeeded.",
            "format": "int32"
          },
          "skipped": {
            "type": "integer",
            "description": "How many ids were not deleted, so nothing changed: the `not_deleted` entries of Ken.Scraper.API.Canonical.ContactBulkRestoreResult.Failed.",
            "format": "int32"
          },
          "succeeded": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactBulkFailure"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Result of `POST /v1/contacts/bulk-restore` (DEV-5219)."
      },
      "ContactBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactBulkFailure"
            },
            "nullable": true
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactCreateRowResult"
            },
            "description": "One item per input row of `contacts.create`, in request order (DEV-6741). Only that route fills it, so it is\nabsent from the JSON of bulk-delete, bulk-pause and bulk-resume.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ContactBulkUpdateItemResult": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "description": "`updated`, `not_found`, `validation_failed`, or `failed`.",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ContactBulkUpdateResult": {
        "type": "object",
        "properties": {
          "updated": {
            "type": "integer",
            "format": "int32"
          },
          "failed": {
            "type": "integer",
            "format": "int32"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactBulkUpdateItemResult"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Result of `POST /v1/contacts/bulk-update`. `results` is in request order."
      },
      "ContactCreateRowResult": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "The row's position in `contacts`, from 0.",
            "format": "int32"
          },
          "status": {
            "type": "string",
            "description": "`created`, `updated`, `skipped` or `failed`.",
            "nullable": true
          },
          "id": {
            "type": "integer",
            "description": "The contact id, when the row was saved.",
            "format": "int64",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "For a skipped or failed row: `duplicate`, `blocklisted`, `already_contacted`,\n`limit_reached`, `invalid_email`, `excluded`, `validation` or `other`.",
            "nullable": true
          },
          "message": {
            "type": "string",
            "description": "For a skipped or failed row, the error text.",
            "nullable": true
          },
          "sendable": {
            "type": "boolean",
            "description": "On a saved row: false when the contact is saved but will not send (added unqualified with no contact allowance\nleft, or do-not-contact).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What `POST /v1/campaigns/{campaignId}/contacts` did with one input row (DEV-6741)."
      },
      "ContactEventModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "DEV-6713: which video activity a `video_event` row is, as its `VideoEventKindNames` wire name\n(`video_viewed`, `video_played`, `video_watched`, `video_liked` or `video_cta_clicked`). Set\nonly on `video_event` rows; omitted on every other row.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ContactFieldModel": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "usages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "isMultiSelect": {
            "type": "boolean"
          },
          "isDefaultExport": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "ContactImportListCheckModel": {
        "required": [
          "always",
          "checks",
          "contacted",
          "noEmailRows",
          "providerMix",
          "rowFlags",
          "titleMix"
        ],
        "type": "object",
        "properties": {
          "rows": {
            "type": "integer",
            "description": "Data rows in the file (`keys.rowCount`).",
            "format": "int32"
          },
          "scannedRows": {
            "type": "integer",
            "description": "Rows checked: the length of the key lists.",
            "format": "int32"
          },
          "truncated": {
            "type": "boolean",
            "description": "True when the key lists hold only the first `scannedRows` rows of the file."
          },
          "cleanupApplied": {
            "type": "boolean",
            "description": "True when every key value went through the import's cleaner first (`keys.cleanup`, default true)."
          },
          "always": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListCheckBucket"
            },
            "description": "What the import skips anyway, first match wins, in this order: `failedValidation`, `missingKey`,\n`blocklist`, `duplicateInFile`, `duplicateInCampaign`, `duplicateInOtherCampaign`. Zero-count\nbuckets included. Up to 3 samples each.",
            "nullable": true
          },
          "contacted": {
            "$ref": "#/components/schemas/ListCheckContacted"
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListCheckItem"
            },
            "description": "The optional fixes, in this order: `invalidEmail`, `noMx`, `catchAll`, `personalEmail`,\n`roleAddress`, `companyContacted`, `companyCap`. `prior` is the expected hard bounce rate of\nthe rows it flags (0 to 1).",
            "nullable": true
          },
          "rowFlags": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "integer",
                "format": "int32"
              }
            },
            "description": "`[rowIndex, mask]` for each row with a flag. Bits: 1 contacted, 2 invalidEmail, 4 noMx, 8 catchAll, 16\n            roleAddress, 32 personalEmail, 64 companyContacted, 128 companyCap.",
            "nullable": true
          },
          "noEmailRows": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "Rows outside the always buckets with no usable email: they send no email, so the bounce estimate leaves them out.",
            "nullable": true
          },
          "baselinePrior": {
            "type": "number",
            "description": "The bounce prior of a row with an email and no email flag.",
            "format": "double"
          },
          "bounce": {
            "$ref": "#/components/schemas/ListCheckBounce"
          },
          "willAdd": {
            "type": "integer",
            "description": "Rows the import adds with every default.",
            "format": "int32"
          },
          "companyContactedDays": {
            "type": "integer",
            "description": "The window of `companyContacted`: the campaign's recently-emailed window, else 90 days.",
            "format": "int32"
          },
          "companyCap": {
            "type": "integer",
            "description": "People per company that `companyCap` keeps.",
            "format": "int32"
          },
          "domainsChecked": {
            "type": "integer",
            "description": "Email domains Kenso has mailbox data for, of `domainsTotal`.",
            "format": "int32"
          },
          "domainsTotal": {
            "type": "integer",
            "format": "int32"
          },
          "titleMix": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListCheckShare"
            },
            "description": "Title bands (`C-level or Founder`, `VP`, `Director`, `Head or Manager`, `Other`) of the\nrows outside the always buckets, shares in whole percent summing to 100; bands with no row left out.",
            "nullable": true
          },
          "providerMix": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListCheckShare"
            },
            "description": "Mailbox providers (`Google`, `Microsoft`, `Other`, `Unknown`) of those rows with an email.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The List check (DEV-5571): what the import skips anyway, the rows the campaign's recently-emailed window drops, and the\noptional fixes for risky rows. `row` in a sample is the 1-based data row number (header excluded); `rows`\nand the first number of each `rowFlags` pair are 0-based indexes into the key lists. A skipped row's reason (for\na download of the skipped rows) is the first match in this order: its `always` bucket, then `contacted`\nwhen it is skipped, then the first check that is on, in `checks` order."
      },
      "ContactImportMemberFiltersBody": {
        "type": "object",
        "properties": {
          "country": {
            "type": "string",
            "description": "Country, at most 200 characters.",
            "nullable": true
          },
          "seniority": {
            "type": "string",
            "description": "Seniority, at most 200 characters.",
            "nullable": true
          },
          "title": {
            "type": "string",
            "description": "Text the job title contains, at most 200 characters.",
            "nullable": true
          },
          "industry": {
            "type": "string",
            "description": "Industry, at most 200 characters.",
            "nullable": true
          },
          "headcountBand": {
            "type": "string",
            "description": "Headcount band, at most 200 characters.",
            "nullable": true
          },
          "hasSendableEmail": {
            "type": "boolean",
            "description": "true keeps only members with a sendable email; false only those without.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "`memberFilters` of a saved_list import. A null or empty value is no filter."
      },
      "ContactImportScanColumnModel": {
        "required": [
          "confidence",
          "csvColumn",
          "reason",
          "samples",
          "targetField"
        ],
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "0-based column index.",
            "format": "int32"
          },
          "csvColumn": {
            "type": "string",
            "description": "The header as sent.",
            "nullable": true
          },
          "targetField": {
            "type": "string",
            "description": "A contact field key (`email`, `full_name`, `profile_url`, ...), `custom_variable` or `skip`.",
            "nullable": true
          },
          "customVariableName": {
            "type": "string",
            "description": "The variable name, only when `targetField` is `custom_variable`.",
            "nullable": true
          },
          "confidence": {
            "type": "string",
            "description": "`high` (the header names the field, or nearly every value is one), `memory` (this workspace mapped the\n            header before), `check` (likely; confirm it) or `skip` (not imported).",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why, in one short sentence.",
            "nullable": true
          },
          "samples": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Up to 3 distinct non-blank values from the sample rows, each at most 120 characters.",
            "nullable": true
          },
          "cleanup": {
            "type": "string",
            "description": "What the import's cleanup would change in this column's sample values, e.g. <c>Cleans 3 of 10 sample values\n(casing, format)</c>; null when nothing changes or the field has no cleaner.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One column's suggestion."
      },
      "ContactImportScanKeys": {
        "type": "object",
        "properties": {
          "rowCount": {
            "type": "integer",
            "format": "int32"
          },
          "cleanup": {
            "type": "boolean",
            "nullable": true
          },
          "email": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "profileUrl": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companyDomain": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companyName": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "companyLinkedinUrl": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "firstName": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "lastName": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "fullName": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "title": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "emailValidity": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "otherEmails": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "nullable": true
          },
          "otherEmailValidity": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ContactImportScanModel": {
        "required": [
          "columns",
          "listKind"
        ],
        "type": "object",
        "properties": {
          "columns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContactImportScanColumnModel"
            },
            "description": "One per header, in header order.",
            "nullable": true
          },
          "listKind": {
            "type": "string",
            "description": "`company` when no column maps to `email`, `profile_url`, `first_name`, `last_name` or\n            `full_name` and one maps to `company_name`, `company_domain` or `company_linkedin_url`;\n            otherwise `people`.",
            "nullable": true
          },
          "check": {
            "$ref": "#/components/schemas/ContactImportListCheckModel"
          }
        },
        "additionalProperties": false,
        "description": "The suggested Kenso field of every column of an import file (DEV-1529)."
      },
      "ContactImportScanRequest": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "description": "Required: `csv`, `google_sheets` or `airtable`.",
            "nullable": true
          },
          "target": {
            "type": "string",
            "description": "`campaign` (the default) or `people` (only the fields a people import takes).",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "Required with target campaign: a campaign of the workspace.",
            "format": "int64",
            "nullable": true
          },
          "headers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The header row: 1 to 200 names, each at most 500 characters.",
            "nullable": true
          },
          "sampleRows": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "description": "Up to 200 data rows. A row shorter than the headers reads as blanks; extra cells are ignored. Each cell at most\n2,000 characters.",
            "nullable": true
          },
          "keys": {
            "$ref": "#/components/schemas/ContactImportScanKeys"
          }
        },
        "additionalProperties": false,
        "description": "The body of `POST /v1/contact-imports/scans` (DEV-1529): an import file's header and sample rows."
      },
      "ContactImportSkipsModel": {
        "type": "object",
        "properties": {
          "duplicateInCampaign": {
            "type": "integer",
            "format": "int32"
          },
          "duplicateInOtherCampaign": {
            "type": "integer",
            "format": "int32"
          },
          "duplicateInSource": {
            "type": "integer",
            "format": "int32"
          },
          "alreadyContacted": {
            "type": "integer",
            "format": "int32"
          },
          "blocklist": {
            "type": "integer",
            "format": "int32"
          },
          "failedValidation": {
            "type": "integer",
            "format": "int32"
          },
          "salesNavigatorProfileUnresolved": {
            "type": "integer",
            "format": "int32"
          },
          "other": {
            "type": "integer",
            "format": "int32"
          },
          "missingKey": {
            "type": "integer",
            "format": "int32"
          },
          "invalidEmail": {
            "type": "integer",
            "format": "int32"
          },
          "noMx": {
            "type": "integer",
            "format": "int32"
          },
          "catchAll": {
            "type": "integer",
            "format": "int32"
          },
          "personalEmail": {
            "type": "integer",
            "format": "int32"
          },
          "roleAddress": {
            "type": "integer",
            "format": "int32"
          },
          "companyContacted": {
            "type": "integer",
            "format": "int32"
          },
          "companyCap": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Rows a campaign `contact_import` job skipped, by reason (DEV-5235). The duplicate counts name the rule that dropped\nthe row: a contact already in this campaign, a contact in another campaign of the workspace (the campaign dedups against\nother campaigns), an earlier row of the same import, or the campaign's recently-emailed window."
      },
      "ContactMailboxProviderModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`detected`: `slug`/`name` name the host. `unknown`: the domain was checked and no host\n            matched, or the contact has no email. `pending`: the domain is not checked yet.",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "description": "Catalog slug, for example `google_workspace`. Only with `detected`.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-5062: the host of a contact's mailbox (for example Google Workspace or Microsoft 365)."
      },
      "ContactModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignListId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "companyId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "companyEmailName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "profileUrn": {
            "type": "string",
            "nullable": true
          },
          "isOpenLink": {
            "type": "boolean",
            "nullable": true
          },
          "jsonGeoLocation": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "isQualified": {
            "type": "boolean"
          },
          "doNotContact": {
            "type": "boolean"
          },
          "sequenceStoppedAt": {
            "type": "string",
            "description": "When this contact's sequence in its campaign was stopped (not DNC). Absent while it runs.",
            "format": "date-time",
            "nullable": true
          },
          "sequenceStopReason": {
            "type": "string",
            "description": "Why the sequence stopped, as stored: `paused` (a member paused the lead),\n`account_play`, or a later value. Absent while it runs.",
            "nullable": true
          },
          "isDecisionMaker": {
            "type": "boolean"
          },
          "qualityScore": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "qualityReasoning": {
            "type": "string",
            "nullable": true
          },
          "profileImage": {
            "type": "string",
            "nullable": true
          },
          "qualificationResponse": {
            "type": "string",
            "nullable": true
          },
          "segmentationReasoning": {
            "type": "string",
            "nullable": true
          },
          "experiencesJson": {
            "type": "string",
            "nullable": true
          },
          "customVariables": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "emailsSent": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "clicks": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "replies": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "unsubscribes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bounces": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "positiveReplies": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "connectionRequestsSent": {
            "type": "integer",
            "description": "DEV-2825: LinkedIn connection requests sent to this contact (confirmed only). The four LinkedIn counters are\nomitted when the contact has no LinkedIn lane and no confirmed LinkedIn send, like the email stats.",
            "format": "int32",
            "nullable": true
          },
          "connectionsAccepted": {
            "type": "integer",
            "description": "DEV-2825: LinkedIn lanes where the contact accepted Kenso's connection request.",
            "format": "int32",
            "nullable": true
          },
          "linkedInMessagesSent": {
            "type": "integer",
            "description": "DEV-2825: LinkedIn messages and InMails sent to this contact (confirmed only).",
            "format": "int32",
            "nullable": true
          },
          "linkedInReplies": {
            "type": "integer",
            "description": "DEV-2825: LinkedIn lanes where the contact replied on LinkedIn.",
            "format": "int32",
            "nullable": true
          },
          "headline": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "countryIso2": {
            "type": "string",
            "nullable": true
          },
          "companyLogo": {
            "type": "string",
            "nullable": true
          },
          "emailEnrichmentProviders": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "linkedInUrlNameMismatch": {
            "type": "boolean"
          },
          "segmentName": {
            "type": "string",
            "nullable": true
          },
          "missingRequiredVariableKeys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "emailValidity": {
            "$ref": "#/components/schemas/EmailValidityEnum"
          },
          "emailFromKenPool": {
            "type": "boolean",
            "description": "DEV-5976: true when the email Ken.Scraper.API.Canonical.ContactModel.EmailValidity describes came from Kenso's email database, free. Absent\nwithout a Safe or Verified email.",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "companySize": {
            "type": "string",
            "nullable": true
          },
          "companyType": {
            "type": "string",
            "nullable": true
          },
          "companyIndustry": {
            "type": "string",
            "nullable": true
          },
          "companyLocation": {
            "type": "string",
            "nullable": true
          },
          "companyTechnologies": {
            "type": "string",
            "nullable": true
          },
          "companyLinkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "companyLinkedInIdent": {
            "type": "string",
            "nullable": true
          },
          "companyEmployeeCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companySpecialities": {
            "type": "string",
            "nullable": true
          },
          "companyDescription": {
            "type": "string",
            "nullable": true
          },
          "companyCrunchBaseUrl": {
            "type": "string",
            "nullable": true
          },
          "companyJsonLocation": {
            "type": "string",
            "nullable": true
          },
          "companyFoundedYear": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "headquartersCity": {
            "type": "string",
            "nullable": true
          },
          "headquartersState": {
            "type": "string",
            "nullable": true
          },
          "headquartersCountry": {
            "type": "string",
            "nullable": true
          },
          "seniorityLevel": {
            "type": "string",
            "nullable": true
          },
          "function": {
            "type": "string",
            "nullable": true
          },
          "yearsOfExperience": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "languages": {
            "type": "string",
            "nullable": true
          },
          "outreachLanguage": {
            "type": "string",
            "description": "DEV-1919: the locale Ken writes to this contact in (`fr-FR`; a bare ISO 639-1 code for a language with no\nmarket pack). Omitted until Ken resolves one. `PATCH` sets it by hand and locks it.",
            "nullable": true
          },
          "outreachFormality": {
            "$ref": "#/components/schemas/OutreachFormalityEnum"
          },
          "outreachLanguageSource": {
            "$ref": "#/components/schemas/OutreachLanguageSourceEnum"
          },
          "outreachLanguageConfidence": {
            "type": "number",
            "description": "0 to 1: 1 for a language a person set, 0 for the campaign's source language.",
            "format": "float",
            "nullable": true
          },
          "outreachLanguageLocked": {
            "type": "boolean",
            "description": "True when a person set the language: no import, enrichment or reply replaces it."
          },
          "phoneNumber": {
            "type": "string",
            "nullable": true
          },
          "phoneNumberValidity": {
            "$ref": "#/components/schemas/PhoneNumberValidityEnum"
          },
          "phoneCountryAssumed": {
            "type": "boolean",
            "description": "True when Kenso added the phone number's country code itself: a number typed without one was read as a US number\n(+1). Unverified; the app shows a warning next to it."
          },
          "lastJobTitle": {
            "type": "string",
            "nullable": true
          },
          "lastJobDescription": {
            "type": "string",
            "nullable": true
          },
          "employmentType": {
            "type": "string",
            "nullable": true
          },
          "employmentLocation": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "skills": {
            "type": "string",
            "nullable": true
          },
          "education": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "accountPlay": {
            "$ref": "#/components/schemas/ContactAccountPlayModel"
          },
          "securityGateway": {
            "$ref": "#/components/schemas/ContactSecurityGatewayModel"
          },
          "mailboxProvider": {
            "$ref": "#/components/schemas/ContactMailboxProviderModel"
          }
        },
        "additionalProperties": { },
        "example": {
          "id": 90125,
          "campaignId": 4821,
          "segmentId": 1207,
          "campaignListId": 3305,
          "companyId": 22841,
          "companyName": "Northwind Labs",
          "companyEmailName": "Northwind",
          "firstName": "Amanda",
          "lastName": "Chen",
          "email": "amanda.chen@northwind.example.com",
          "linkedInUrl": "https://www.linkedin.com/in/amanda-chen-northwind",
          "title": "VP of Engineering",
          "isQualified": true,
          "doNotContact": false,
          "isDecisionMaker": true,
          "qualityScore": 86,
          "qualityReasoning": "Leads a 40-person engineering team at a 120-person B2B SaaS company that is hiring engineers.",
          "segmentationReasoning": "VP of Engineering, which matches the Engineering leaders segment.",
          "customVariables": {
            "open_roles": "12 engineering roles"
          },
          "emailsSent": 2,
          "clicks": 0,
          "replies": 1,
          "unsubscribes": 0,
          "bounces": 0,
          "positiveReplies": 1,
          "headline": "VP of Engineering at Northwind Labs",
          "location": "Austin, Texas, United States",
          "city": "Austin",
          "state": "Texas",
          "country": "United States",
          "countryIso2": "US",
          "companyLogo": "https://cdn.example.com/companies/22841/logo.png",
          "linkedInUrlNameMismatch": false,
          "segmentName": "Engineering leaders",
          "emailValidity": "safe",
          "emailFromKenPool": false,
          "companyDomain": "northwind.example.com",
          "companySize": "51-200",
          "companyIndustry": "Software Development",
          "companyLocation": "Austin, Texas, United States",
          "companyEmployeeCount": 120,
          "companyDescription": "Northwind Labs builds developer onboarding software for engineering teams.",
          "companyFoundedYear": 2017,
          "headquartersCity": "Austin",
          "headquartersState": "Texas",
          "headquartersCountry": "United States",
          "seniorityLevel": "VP",
          "function": "Engineering",
          "yearsOfExperience": 14,
          "outreachLanguage": "en-US",
          "outreachLanguageSource": "country",
          "outreachLanguageConfidence": 0.8,
          "outreachLanguageLocked": false,
          "phoneCountryAssumed": false,
          "createdAt": "2026-09-23T15:02:11Z",
          "updatedAt": "2026-10-13T16:22:05Z"
        }
      },
      "ContactSecurityGatewayModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`detected`: a gateway was found and `slug`/`name` name it. `none`: none found, or the\n            contact has no email or a free-mail address. `pending`: the domain is not checked yet.",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "description": "Catalog slug, for example `proofpoint`. Only with `detected`.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-5062: the email security gateway in front of a contact's email."
      },
      "ContactWebsitePageModel": {
        "type": "object",
        "properties": {
          "pageType": {
            "type": "string",
            "description": "Page type: `home`, `about`, `pricing`, `contact`, `blog`,\n`blog_articles`, `services`, `products`, `testimonials`,\n`case_studies`, `results`, `portfolio`, `gallery`, `reviews`,\n`privacy_policy`, `terms_of_service`, `careers`, `team`, or\n`other`. Clients tolerate unknown values.",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "The page URL. Omitted when unknown.",
            "nullable": true
          },
          "title": {
            "type": "string",
            "description": "The page title. Omitted when unknown.",
            "nullable": true
          },
          "markdown": {
            "type": "string",
            "description": "The page content as markdown, at most 20,000 characters.",
            "nullable": true
          },
          "scrapedAt": {
            "type": "string",
            "description": "When the page was captured: the archive capture date, the scrape time for live pages,\nor the upload time for imported pages.",
            "format": "date-time"
          },
          "source": {
            "type": "string",
            "description": "`archive` (Common Crawl copy), `live` (scraped by Kenso), or `imported`\n            (supplied in a CSV upload). Clients tolerate unknown values.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One scraped page of the contact's company website."
      },
      "CopySavedListBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "memberFilters": {
            "$ref": "#/components/schemas/SavedListMemberFiltersBody"
          }
        },
        "additionalProperties": false
      },
      "CreateAccessRequestBody": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "page, feature, or credits. Required.",
            "nullable": true
          },
          "key": {
            "type": "string",
            "description": "A page (today ... delivery) or feature (approve ... workspace_settings) wire name; monthly_limit for credits. Required.",
            "nullable": true
          },
          "level": {
            "type": "string",
            "description": "Page requests only: view or edit. Omitted = one level above what you have now.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Optional note for the people who decide, up to 2000 characters.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/access-requests`."
      },
      "CreateAgentActionRequest": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "`cap_move`, `inbox_drop`, `inbox_restore`, `top_up`, `placement_test` or `make_default`.\n            Required.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "The campaign the action changes. Required.",
            "format": "int64",
            "nullable": true
          },
          "args": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonNode"
            },
            "description": "The kind's arguments: `cap_move``{ newCap }`, `inbox_drop``{ inboxId, scope }` (`campaign`,\nthe default when scope is absent, or `inbox` for every campaign it sends on), `inbox_restore``{ inboxId }`, `top_up``{ count }` (the caller also needs Search view and the Import permission),\n`placement_test``{}`, `make_default``{ experimentId }`. Absent is `{}`.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why, in one or two sentences a person reads, up to 500 characters. Required.",
            "nullable": true
          },
          "idempotencyKey": {
            "type": "string",
            "description": "The caller's key for this request, up to 120 characters: a retry with the same key runs once. Absent, the same kind,\ncampaign and args run once per UTC day, and a try that failed runs again.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The body of `POST /v1/agent-team/actions` (DEV-3671)."
      },
      "CreateAiRunRequest": {
        "type": "object",
        "properties": {
          "flow": {
            "type": "string",
            "nullable": true
          },
          "batchSize": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "processAll": {
            "type": "boolean"
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "dryRun": {
            "type": "boolean",
            "description": "True validates the run and returns what it would process (`200`), without queueing it, reserving quota or\nspending credits. Default false."
          }
        },
        "additionalProperties": false
      },
      "CreateBlocklistEntryRequest": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why the value is blocked. Optional, at most 200 characters; blank stores none.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "type": "domain",
          "value": "competitor.example.com",
          "reason": "Current customer"
        }
      },
      "CreateBlocklistRuleBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "stages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "accountTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "enabled": {
            "type": "boolean",
            "nullable": true
          },
          "releaseAfterDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "crmListId": {
            "type": "string",
            "nullable": true
          },
          "crmLifecycles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateBookingLinkBody": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "personId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "meetingTypeId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "hostMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "accountId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "touchId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "assetId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "senderAddress": {
            "type": "string",
            "nullable": true
          },
          "availability": {
            "$ref": "#/components/schemas/AvailabilityScheduleModel"
          }
        },
        "additionalProperties": false
      },
      "CreateBuyerPreviewRequest": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "description": "The campaign whose ICP the buyers are matched to. Required; another workspace's campaign is 404.",
            "format": "int64",
            "nullable": true
          },
          "companies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BuyerPreviewCompanyInput"
            },
            "description": "1 to 50 companies, each with a `name` or a `domain` and an optional `key` echoed back.",
            "nullable": true
          },
          "perCompany": {
            "type": "integer",
            "description": "People per company, 1 to 3 (default 3).",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "POST /v1/contact-imports/buyer-previews body (DEV-5566)."
      },
      "CreateCampaignContactRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "customImageUrl": {
            "type": "string",
            "description": "DEV-6700: https URL of the lead's own image, shown in emails as `{{custom_image}}`; Kenso downloads and\nhosts it. An empty string clears it. Needs campaign images on the workspace.",
            "nullable": true
          },
          "customVariables": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "nullable": true
            },
            "description": "Custom variables for this contact, as an object of string values (for example `rd_first_line`). Keys are\nnormalized the same way as CSV import columns. Values merge into the contact's existing custom variables; a key\nnew to the campaign is added to its custom-variable catalog with AI context off. A null or empty value clears that\nkey on an existing contact. At most 50 keys per contact.",
            "nullable": true
          },
          "emailValidity": {
            "$ref": "#/components/schemas/EmailValidityEnum"
          }
        },
        "additionalProperties": false
      },
      "CreateCampaignContactsRequest": {
        "type": "object",
        "properties": {
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateCampaignContactRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateCampaignRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "contactLimit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "DEV-1274: `sales` (default) or `recruiting`. A recruiting campaign needs the recruiting flag.",
            "nullable": true
          },
          "roleId": {
            "type": "integer",
            "description": "DEV-1274: the primary role of a recruiting campaign: a live role of this workspace.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "name": "Q4 SaaS founders",
          "contactLimit": 2500,
          "kind": "sales"
        }
      },
      "CreateCliLoginRequest": {
        "type": "object",
        "properties": {
          "deviceName": {
            "type": "string",
            "description": "The machine the CLI runs on, shown on the approval page. 1 to 100 characters.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/cli/logins`."
      },
      "CreateContactExportBody": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "contacts (workspace filters, the default), campaign, clicked, advanced or events.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "The campaign to export. Required for every kind except contacts, and for contacts with readyOnly.",
            "format": "int64",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "description": "Kind contacts only: the campaign segment to export.",
            "format": "int64",
            "nullable": true
          },
          "isQualified": {
            "type": "boolean",
            "description": "Kinds contacts and campaign: only qualified (true) or only unqualified (false) contacts.",
            "nullable": true
          },
          "hasValidEmail": {
            "type": "boolean",
            "description": "Kind contacts: only contacts with (true) or without (false) a valid email.",
            "nullable": true
          },
          "doNotContact": {
            "type": "boolean",
            "description": "Kind contacts: only do-not-contact (true) or only contactable (false) contacts.",
            "nullable": true
          },
          "q": {
            "type": "string",
            "description": "Kind contacts: search text, at most 200 characters.",
            "nullable": true
          },
          "contactIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Kind contacts: export only these contacts, at most 1,000 ids.",
            "nullable": true
          },
          "excludedContactIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Kind contacts: leave these contacts out, at most 1,000 ids.",
            "nullable": true
          },
          "fields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The columns to write, at most 80 names. Omitted writes the kind's default columns.",
            "nullable": true
          },
          "readyOnly": {
            "type": "boolean",
            "description": "Kind contacts only, with campaignId: only contacts ready to send."
          },
          "includeEmails": {
            "type": "boolean",
            "description": "Kinds campaign, clicked and advanced: include email columns. Default true.",
            "nullable": true
          },
          "includeCompany": {
            "type": "boolean",
            "description": "Kinds campaign, clicked and advanced: include company columns. Default true.",
            "nullable": true
          },
          "includeClickEvents": {
            "type": "boolean",
            "description": "Kind advanced: include click events. Default true.",
            "nullable": true
          },
          "includeTotalClicks": {
            "type": "boolean",
            "description": "Kind advanced: include the total click count. Default true.",
            "nullable": true
          },
          "occurredAfter": {
            "type": "string",
            "description": "Kind events: start of the range (required).",
            "format": "date-time",
            "nullable": true
          },
          "occurredBefore": {
            "type": "string",
            "description": "Kind events: end of the range (required).",
            "format": "date-time",
            "nullable": true
          },
          "campaignIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Kind contacts only: 1 to 50 campaigns of the workspace. Not together with campaignId.",
            "nullable": true
          },
          "listId": {
            "type": "integer",
            "description": "Kind contacts only: contacts of this import list (a contact's listId).",
            "format": "int64",
            "nullable": true
          },
          "createdAfter": {
            "type": "string",
            "description": "Kind contacts only: contacts created at or after this time.",
            "format": "date-time",
            "nullable": true
          },
          "createdBefore": {
            "type": "string",
            "description": "Kind contacts only: contacts created before this time (exclusive).",
            "format": "date-time",
            "nullable": true
          },
          "maxRows": {
            "type": "integer",
            "description": "Kind contacts only: at most this many rows, 1 to 50000.",
            "format": "int32",
            "nullable": true
          },
          "skipRows": {
            "type": "integer",
            "description": "Kind contacts only: skip this many matching rows first, in contact id order.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Documentation only (DEV-6703): JSON body of `POST /v1/contact-exports`, which the action reads itself into\n`CreateContactExportRequest`. No action binds this type. Every property is optional."
      },
      "CreateContactImportBody": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "description": "The campaign to import into. Required with target campaign; ignored with target people.",
            "format": "int64"
          },
          "source": {
            "type": "string",
            "description": "campaign, segment, search, people, event, linkedin_connections, sales_navigator, linkedin_url, google_sheets, airtable\nor saved_list. A source behind a feature that is off answers like an unknown source (or 404 for linkedin_url).",
            "nullable": true
          },
          "target": {
            "type": "string",
            "description": "campaign (the default) adds the rows to campaignId as contacts; people runs them through person intake as workspace people.",
            "nullable": true
          },
          "sourceCampaignId": {
            "type": "integer",
            "description": "source campaign: the campaign to copy contacts from.",
            "format": "int64",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "description": "Not supported by source search or linkedin_connections (400): their contacts go to the campaign's default segment.",
            "format": "int64",
            "nullable": true
          },
          "contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchContactDTO"
            },
            "description": "source search: 1 to 1,000 contact rows.",
            "nullable": true
          },
          "personIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "source people: 1 to 1,000 workspace people to add as contacts.",
            "nullable": true
          },
          "eventId": {
            "type": "integer",
            "description": "source event: the outbound event whose attendees become contacts.",
            "format": "int64",
            "nullable": true
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "source event: the roles to import (attendee, exhibitor, speaker, sponsor), default every role. source saved_list with\na company list: 1 to 20 job titles to find people for.",
            "nullable": true
          },
          "includeAccounts": {
            "type": "boolean",
            "description": "source event: true also imports rows whose company is a workspace account. Default false.",
            "nullable": true
          },
          "connectionIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "source linkedin_connections: 1 to 1,000 LinkedIn connection ids from GET /v1/linkedin-connections.",
            "nullable": true
          },
          "linkedinAccountId": {
            "type": "integer",
            "description": "source sales_navigator or linkedin_url: a LinkedIn seat the caller connected, which reads url.",
            "format": "int64",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "source sales_navigator: a Sales Navigator lead search or lead list URL. source linkedin_url: a LinkedIn post, people\nsearch, Sales Navigator search or Sales Navigator lead list URL.",
            "nullable": true
          },
          "spreadsheetId": {
            "type": "string",
            "description": "source google_sheets: the spreadsheet id, or its Google Sheets URL.",
            "nullable": true
          },
          "sheet": {
            "type": "string",
            "description": "source google_sheets: the sheet (tab) title. Omitted reads the first sheet.",
            "nullable": true
          },
          "baseId": {
            "type": "string",
            "description": "source airtable: the Airtable base id (app...).",
            "nullable": true
          },
          "tableId": {
            "type": "string",
            "description": "source airtable: the table id (tbl...) or name. Its field names are the header row.",
            "nullable": true
          },
          "viewId": {
            "type": "string",
            "description": "source airtable: a view id (viw...) or name; only its records are imported. Omitted reads the whole table.",
            "nullable": true
          },
          "columnMappings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CsvColumnMapping"
            },
            "description": "source google_sheets or airtable: which column feeds which contact field, as for a CSV upload. Omitted maps the header\nrow by the import's aliases. Refused with source saved_list.",
            "nullable": true
          },
          "maxLeads": {
            "type": "integer",
            "description": "source linkedin_url: default 500; at most 2,000 for a post, 1,000 for a people search, 2,500 for Sales Navigator.",
            "format": "int32",
            "nullable": true
          },
          "postKinds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "source linkedin_url, post URLs only: reaction, comment, or both (default).",
            "nullable": true
          },
          "savedListId": {
            "type": "integer",
            "description": "source saved_list: the saved list whose members are imported.",
            "format": "int64",
            "nullable": true
          },
          "memberFilters": {
            "$ref": "#/components/schemas/ContactImportMemberFiltersBody"
          },
          "findPeople": {
            "type": "boolean",
            "description": "source saved_list: must be absent or false.",
            "nullable": true
          },
          "importLimit": {
            "type": "integer",
            "description": "source campaign or search: import at most this many contacts. Greater than 0.",
            "format": "int32",
            "nullable": true
          },
          "importOffset": {
            "type": "integer",
            "description": "source campaign: skip this many source contacts first. 0 or more.",
            "format": "int32",
            "nullable": true
          },
          "onlyImportQualifiedContacts": {
            "type": "boolean",
            "description": "source campaign: only the source's qualified contacts. Default false.",
            "nullable": true
          },
          "onlyImportValidContacts": {
            "type": "boolean",
            "description": "source campaign: only contacts with a valid email. Default false.",
            "nullable": true
          },
          "deduplicateCampaignIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "source campaign: leave out people already in these campaigns of the workspace. 1 to 50 ids.",
            "nullable": true
          },
          "deduplicationMode": {
            "type": "string",
            "description": "source campaign: none, by_email (the default) or by_data (first name, last name and company).",
            "nullable": true
          },
          "allowReimport": {
            "type": "boolean",
            "description": "source campaign: repeat a finished copy from the same source campaign. Default false.",
            "nullable": true
          },
          "copyDataEnrichment": {
            "type": "boolean",
            "description": "source campaign: keep the source contacts' data enrichment results (LinkedIn profile, posts). Default false.",
            "nullable": true
          },
          "copyEmailEnrichment": {
            "type": "boolean",
            "description": "source campaign or segment: keep the source contacts' email finder results. Default false.",
            "nullable": true
          },
          "triggerPostProcessing": {
            "type": "boolean",
            "description": "source search: start enrichment and the AI flows after the import. Default true.",
            "nullable": true
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "source search: workspace contact tags to put on every imported contact. 1 to 50 ids.",
            "nullable": true
          },
          "sourceSegmentId": {
            "type": "integer",
            "description": "source segment: the workspace segment to copy into campaignId as a new segment. Required.",
            "format": "int64",
            "nullable": true
          },
          "copyQualification": {
            "type": "boolean",
            "description": "source segment: keep the source contacts' AI qualification results. Default false.",
            "nullable": true
          },
          "copyEmailVerification": {
            "type": "boolean",
            "description": "source segment: keep the source contacts' email verification results. Default false.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "JSON body of `POST /v1/contact-imports`. `source` decides which other properties are read; see the operation\ndescription for each source, its limits and the feature it needs."
      },
      "CreateContactImportFormBody": {
        "required": [
          "file"
        ],
        "type": "object",
        "properties": {
          "file": {
            "type": "string",
            "description": "The CSV file. Required, non-empty, with a .csv extension. Row 1 is the header.",
            "format": "binary"
          },
          "campaignId": {
            "type": "integer",
            "description": "The campaign to import into. Required with target campaign; ignored with target people.",
            "format": "int64"
          },
          "source": {
            "type": "string",
            "description": "csv, or omitted.",
            "nullable": true
          },
          "target": {
            "type": "string",
            "description": "campaign (the default) or people (behind the lead_intake feature, needs Accounts edit).",
            "nullable": true
          },
          "columnMappings": {
            "type": "string",
            "description": "A JSON array of column mappings (csvColumn, targetField, and for a custom variable customVariableName, useAsAiContext,\nisRequiredForSending). A mapped column the header row lacks is 400 validation_failed. Omitted maps the header row by\nthe import's aliases.",
            "nullable": true
          },
          "fixes": {
            "type": "string",
            "description": "A JSON array of List check fixes (missingKey, invalidEmail, noMx, catchAll, personalEmail, roleAddress,\ncompanyContacted, companyCap): the rows the List check flags for them are dropped. Send it only to use it: the field's\npresence needs the csv_import_check feature (otherwise 400 validation_failed) and is refused with target people.",
            "nullable": true
          },
          "includeRecentlyContacted": {
            "type": "boolean",
            "description": "true keeps the rows the campaign's recently-emailed window would skip, for this import only. Send it only as true:\nthe field's presence, even false, needs the csv_import_check feature (otherwise 400 validation_failed) and is refused\nwith target people."
          },
          "cleanup": {
            "type": "boolean",
            "description": "true cleans the name, email, title, company, domain, LinkedIn URL and phone cells. Send it only as true: the field's\npresence, even false, needs the csv_import_check feature (otherwise 400 validation_failed) and is refused with\ntarget people."
          },
          "emailsFoundByKen": {
            "type": "boolean",
            "description": "Staff only: true stamps every imported email as found by Kenso, and true from anyone else is 403. Send it only as\ntrue: any value is refused with target people."
          }
        },
        "additionalProperties": false,
        "description": "`multipart/form-data` body of `POST /v1/contact-imports`: a CSV upload (source csv), up to 400 MB."
      },
      "CreateCreditEstimateRequest": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "`campaign`, `build`, `infra`, `accounts`, `leads` or `places`.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "Campaign only: read target leads, step count and personalization from this campaign.",
            "format": "int64",
            "nullable": true
          },
          "targetLeads": {
            "type": "integer",
            "description": "Campaign only: finished leads, 1-1,000,000. Required unless the campaign's contact limit is below\n            1,000,000 (the default, which is not read as a target).",
            "format": "int32",
            "nullable": true
          },
          "sequenceSteps": {
            "type": "integer",
            "description": "Campaign only: sequence steps, 1-50 (default: the campaign's, else 3).",
            "format": "int32",
            "nullable": true
          },
          "personalization": {
            "type": "boolean",
            "description": "Campaign only: whether leads are personalized (default: the campaign's, else true).",
            "nullable": true
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditEstimateInfraItemRequest"
            },
            "description": "Infra only: 1-50 purchases.",
            "nullable": true
          },
          "accountCount": {
            "type": "integer",
            "description": "Accounts only: accounts to add, 1-1,000.",
            "format": "int32",
            "nullable": true
          },
          "leadCount": {
            "type": "integer",
            "description": "Leads only: leads to import, 1-1,000,000.",
            "format": "int32",
            "nullable": true
          },
          "pages": {
            "type": "integer",
            "description": "Places only: search pages of up to 200 places, 0-1,000. Send pages or opens above 0.",
            "format": "int32",
            "nullable": true
          },
          "opens": {
            "type": "integer",
            "description": "Places only: detail, reviews or photos opens, 0-100,000. The first 500 a workspace a UTC day are free.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "`credit-estimates.create` body."
      },
      "CreateCustomVariableRequest": {
        "type": "object",
        "properties": {
          "variableKey": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "useAsAiContext": {
            "type": "boolean",
            "nullable": true
          },
          "isRequiredForSending": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateDomainHealthCheckRequest": {
        "type": "object",
        "properties": {
          "domainIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body for `POST /v1/domain-health-checks`.\nOmit `domainIds` to check every domain in the workspace. Maximum 1,000 ids."
      },
      "CreateEmailFindBody": {
        "type": "object",
        "properties": {
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "linkedinUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateEnrichmentRunRequest": {
        "type": "object",
        "properties": {
          "minConfidence": {
            "type": "number",
            "format": "float",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateImageVariableRequest": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "The token key; normalized (`Hero Image` is stored as `hero_image`). Fixed after create.",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "`shared` or `per_prospect`. Fixed after create.",
            "nullable": true
          },
          "prompt": {
            "type": "string",
            "description": "Required for per_prospect, at most 4,000 characters.",
            "nullable": true
          },
          "references": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Reference wire names; a shared variable may use only `sender_logo`.",
            "nullable": true
          },
          "model": {
            "type": "string",
            "description": "Default `openai/gpt-image-2.5-sunburst`.",
            "nullable": true
          },
          "size": {
            "type": "string",
            "description": "Default `1024x1024`.",
            "nullable": true
          },
          "quality": {
            "type": "string",
            "description": "Default `medium`.",
            "nullable": true
          },
          "spellingCheck": {
            "type": "boolean",
            "description": "Default true.",
            "nullable": true
          },
          "requiredForSending": {
            "type": "boolean",
            "description": "Default false.",
            "nullable": true
          },
          "enabled": {
            "type": "boolean",
            "description": "Absent or false only: a new variable starts off, and `true` is a 400 on `enabled`. Turn it on with PATCH\nafter reading its estimate.",
            "nullable": true
          },
          "altText": {
            "type": "string",
            "description": "At most 200 characters.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "JSON body of `POST /v1/campaigns/{campaignId}/image-variables`. Absent optional fields take their defaults."
      },
      "CreateInboundWebhookRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "samplePayloadJson": {
            "type": "string",
            "nullable": true
          },
          "mapping": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookAssignment"
            },
            "nullable": true
          },
          "preset": {
            "type": "string",
            "description": "A preset (`hubspot_forms`, `typeform`, `webflow`, `tally`, `rb2b`, `vector`,\n`generic`, `zapier`, `make`, `n8n`); fills Ken.Scraper.API.Dtos.CreateInboundWebhookRequest.Mapping when that is empty.",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "`campaign` or `people`. Optional: the route decides it (under a campaign, `campaign`; at the\n            workspace level, `people`), and a different value is `400`.",
            "nullable": true
          },
          "app": {
            "type": "string",
            "description": "A `people` webhook's sending app: `zapier`, `make` or `n8n`. The `zapier`,\n`make` and `n8n` presets set it.",
            "nullable": true
          },
          "defaultOwnerMemberId": {
            "type": "integer",
            "description": "A `people` webhook only: the member who owns the people it creates. Omit it to let the intake settings decide.",
            "format": "int64",
            "nullable": true
          },
          "createAccounts": {
            "type": "boolean",
            "description": "A `people` webhook only: `false` never creates the person's account; `true` or omitted, the intake settings decide.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateInboxConnectSessionRequest": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "nullable": true
          },
          "purpose": {
            "type": "string",
            "nullable": true
          },
          "returnTo": {
            "type": "string",
            "description": "Optional dashboard path the connect returns to (DEV-1611), for example `/42/delivery?tab=inboxes`. A\nrelative path with one leading `/`: no scheme, host, `//`, backslash or control characters, at\nmost 512 characters. Omit it to return to the app's default page.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Start a Gmail or Microsoft connect (DEV-1652). `provider` is `google` or `microsoft`;\n`purpose` is `primary` (the caller's own mailbox, needs Kenso Accounts) or `campaign`."
      },
      "CreateInboxImportRequest": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateInboxImportRow"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/inbox-imports`: 1 to 500 SMTP/IMAP inboxes, usually parsed from a CSV."
      },
      "CreateInboxImportRow": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "description": "Accepted and not applied: the single SMTP create does not take it. Set it with `PATCH /v1/inboxes/{inboxId}`.",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "description": "Accepted and not applied: the single SMTP create does not take it. Set it with `PATCH /v1/inboxes/{inboxId}`.",
            "nullable": true
          },
          "username": {
            "type": "string",
            "description": "Login for SMTP AUTH and IMAP LOGIN. Defaults to `email`.",
            "nullable": true
          },
          "password": {
            "type": "string",
            "description": "Input only. Never stored with the job, logged, or returned.",
            "nullable": true
          },
          "smtpHost": {
            "type": "string",
            "nullable": true
          },
          "smtpPort": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "imapHost": {
            "type": "string",
            "nullable": true
          },
          "imapPort": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "smtpStartTls": {
            "type": "boolean",
            "description": "Defaults to true.",
            "nullable": true
          },
          "dailySendLimit": {
            "type": "integer",
            "description": "Accepted and not applied: the single SMTP create does not take it. Set it with `PATCH /v1/inboxes/{inboxId}`.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One inbox, with the same fields as `POST /v1/inboxes`. A row with a missing field fails on its own;\nit does not reject the request."
      },
      "CreateInboxRequest": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          },
          "username": {
            "type": "string",
            "nullable": true
          },
          "password": {
            "type": "string",
            "nullable": true
          },
          "smtpHost": {
            "type": "string",
            "nullable": true
          },
          "smtpPort": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "imapHost": {
            "type": "string",
            "nullable": true
          },
          "imapPort": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "smtpStartTls": {
            "type": "boolean",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "description": "Make this the caller's own mailbox (DEV-1652). Must equal the caller's member id, and the workspace\nneeds Kenso Accounts. Omit for a shared campaign inbox.",
            "format": "int64",
            "nullable": true
          },
          "preset": {
            "type": "string",
            "description": "A mailbox provider preset (DEV-3556), for example `dead_simple_email` or `azure_smtp`: its hosts, ports and\nTLS replace `smtpHost`, `smtpPort`, `imapHost`, `imapPort` and `smtpStartTls`, which\nmay be omitted. Needs the `sending_providers` feature.",
            "nullable": true
          },
          "replyToInboxId": {
            "type": "integer",
            "description": "With a preset that has no IMAP (`azure_smtp`): the workspace inbox Ken reads replies from. Required there,\nignored otherwise.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateLinkedInConnectSessionRequest": {
        "type": "object",
        "properties": {
          "linkedInAccountId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "importConnections": {
            "type": "boolean",
            "description": "Import the seat's connections into Accounts once it connects (DEV-5778). Read on a connect only, while\nlinkedin_connections_import is on; a reconnect keeps the stored setting.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Connect omits the account id. Reconnect accepts `linkedInAccountId` or `linkedinAccountId`."
      },
      "CreateMeetingTypeBody": {
        "type": "object",
        "properties": {
          "lengthMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "locationKind": {
            "type": "string",
            "nullable": true
          },
          "locationDetail": {
            "type": "string",
            "nullable": true
          },
          "minimumNoticeMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bookingWindowDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bufferBeforeMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bufferAfterMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "dailyCap": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "reminderEnabled": {
            "type": "boolean",
            "nullable": true
          },
          "reminderText": {
            "type": "string",
            "nullable": true
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingTypeQuestionInput"
            },
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isSecret": {
            "type": "boolean",
            "nullable": true
          },
          "isEnabled": {
            "type": "boolean",
            "nullable": true
          },
          "isDefault": {
            "type": "boolean",
            "nullable": true
          },
          "availability": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AvailabilityScheduleModel"
              }
            ],
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "hostMemberIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreatePlacementTestRequest": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "description": "Campaign whose email copy is tested.",
            "format": "int64",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "description": "Inbox to test. Mutually exclusive with `domainId` unless `randomScope` is true.",
            "format": "int64",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "description": "Domain to test. Mutually exclusive with `inboxId` unless `randomScope` is true.",
            "format": "int64",
            "nullable": true
          },
          "sequenceVersionId": {
            "type": "integer",
            "description": "Sequence version to send. Absent uses the live saved copy.",
            "format": "int64",
            "nullable": true
          },
          "sampleVariables": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "Sample values for sequence variables, keyed by variable name.",
            "nullable": true
          },
          "campaignSegmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "contactId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "randomSegment": {
            "type": "boolean"
          },
          "randomLead": {
            "type": "boolean"
          },
          "randomScope": {
            "type": "boolean"
          },
          "randomCopyVersion": {
            "type": "boolean"
          },
          "openPixel": {
            "type": "boolean",
            "description": "Send the copy with the campaign open pixel, on `link.` or `unsub.` of the test's sending domain\n(whichever serves the pixel first), to compare placement with the pixel on and off. Default false."
          }
        },
        "additionalProperties": false,
        "description": "Body for `POST /v1/placement-tests`.\nSupply `campaignId` and exactly one of `domainId` or `inboxId`,\nunless `randomScope` is true."
      },
      "CreatePromptRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "prompt": {
            "type": "string",
            "nullable": true
          },
          "audienceDescription": {
            "type": "string",
            "nullable": true
          },
          "qualificationCriteria": {
            "type": "string",
            "nullable": true
          },
          "disqualificationCriteria": {
            "type": "string",
            "nullable": true
          },
          "scoringCriteria": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "flow": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "promptTemplateId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "toOutput": {
            "type": "boolean",
            "nullable": true
          },
          "toRewrite": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "order": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "fallbackIfEmpty": {
            "type": "string",
            "nullable": true
          },
          "isRequiredForSending": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateProposalRequest": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "What to change: `cap_move`, `schedule`, `pause`, `resume`, `top_up`, `audience`,\n`copy`, `inbox_drop`, `inbox_restore`, `make_default`, `placement_test`,\n`standing_rule`, `client_update` or `angle`. Required.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "The campaign it changes; omit for a workspace-level kind (`angle`, `standing_rule`, `client_update`).",
            "format": "int64",
            "nullable": true
          },
          "title": {
            "type": "string",
            "description": "The card's title, up to 120 characters. Required.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why, in a few sentences a person reads, up to 1000 characters. Required.",
            "nullable": true
          },
          "args": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/JsonNode"
            },
            "description": "The kind's arguments, applied as they are when a person approves. Absent is `{}`.",
            "nullable": true
          },
          "clientYes": {
            "type": "string",
            "description": "On a client workspace, the client's yes to a schedule or volume change in the person's own words, with who, where and\nwhen (up to 300 characters). The approver still confirms it. Omit when there is none.",
            "nullable": true
          },
          "urgent": {
            "type": "boolean",
            "description": "Puts the card first in Approvals. Default false.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The body of `POST /v1/agent-team/proposals` (DEV-3671)."
      },
      "CreateReplyTemplateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "authorSource": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateSavedListBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "visibility": {
            "type": "string",
            "nullable": true
          },
          "icpTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateSavedListInviteBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateSavedListSourceBody": {
        "type": "object",
        "properties": {
          "sourceType": {
            "type": "string",
            "nullable": true
          },
          "parameters": {
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateSearchImportRequest": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "description": "The campaign in this workspace that receives the people.",
            "format": "int64",
            "nullable": true
          },
          "personIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Search person ids to import.",
            "nullable": true
          },
          "searchFilters": {
            "description": "A people search body, as sent to `POST /v1/search/people`. Imports every match, up to `limit`.",
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "description": "Most people a `searchFilters` import adds.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body for `POST /v1/search/imports`. Send exactly one of `personIds` and `searchFilters`."
      },
      "CreateSegmentRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "segmentationType": {
            "type": "string",
            "nullable": true
          },
          "abTestPercentage": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "filterCriteria": {
            "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaDTO"
          }
        },
        "additionalProperties": false,
        "example": {
          "name": "Engineering leaders",
          "description": "VPs and heads of engineering at B2B SaaS companies with 50 to 500 employees.",
          "segmentationType": "ai",
          "sortOrder": 1
        }
      },
      "CreateShareInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "accountIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "items": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "permission": {
            "type": "string",
            "nullable": true
          },
          "expiry": {
            "type": "string",
            "nullable": true
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "holdLaunch": {
            "type": "boolean"
          },
          "recurringReport": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "CreateSignalRequest": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "contactId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignSegmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "payload": {
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "dedupKey": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateSignalsRequest": {
        "type": "object",
        "properties": {
          "isSynthetic": {
            "type": "boolean",
            "nullable": true
          },
          "signals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreateSignalRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateTagRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "entityTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Omitted or empty: every entity type, account and linkedin_account included.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "name": "Hot lead",
          "description": "Asked for a call or pricing",
          "color": "#FFD6A5",
          "entityTypes": [
            "contact",
            "reply"
          ]
        }
      },
      "CreateThreadMessageRequest": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "senderEmailId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "confirmSuppressed": {
            "type": "boolean",
            "description": "Email only: send even though the contact is do-not-contact, blocklisted or unsubscribed.\nSet only after the user confirmed a `409 invalid_state` for a suppressed contact."
          },
          "archiveAfterSend": {
            "type": "boolean",
            "description": "Email only: archive the thread once the reply sends. A reply waiting on a client seat's approval\narchives when the approved reply sends, never while it waits, and a skipped one leaves the thread\nas it was (DEV-2043)."
          },
          "to": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadAddressRequest"
            },
            "description": "Email only: who the reply goes to, each one bare email address. Omitted, the reply goes to the thread's sender\n(to everyone on the thread with Ken.Scraper.API.Dtos.CreateThreadMessageRequest.ReplyAll). A LinkedIn thread refuses it (DEV-2537).",
            "nullable": true
          },
          "cc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadAddressRequest"
            },
            "description": "Email only: Cc recipients, each one bare email address. A LinkedIn thread refuses it (DEV-2537).",
            "nullable": true
          },
          "bcc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadAddressRequest"
            },
            "description": "Email only: Bcc recipients, each one bare email address. A LinkedIn thread refuses it (DEV-2537).",
            "nullable": true
          },
          "replyAll": {
            "type": "boolean",
            "description": "Email only: without Ken.Scraper.API.Dtos.CreateThreadMessageRequest.To, reply to the thread's sender, To and Cc, less the sending inbox. A\nLinkedIn thread refuses it (DEV-2537)."
          },
          "attachmentIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Email only: `att_` ids of files uploaded against this thread (`POST /v1/attachments` with the thread's\nnewest message as `messageId`). A LinkedIn thread refuses it (DEV-2537).",
            "nullable": true
          },
          "contentType": {
            "type": "string",
            "description": "Email only: `html` (the default) or `text`. A LinkedIn thread refuses it (DEV-2537).",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateThreadRecipient": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateThreadRequest": {
        "type": "object",
        "properties": {
          "senderInboxId": {
            "type": "integer",
            "description": "A shared cold inbox of the workspace (`GET /v1/inboxes`). Never a member's own mailbox.",
            "format": "int64",
            "nullable": true
          },
          "to": {
            "$ref": "#/components/schemas/CreateThreadRecipient"
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "description": "The email body as HTML.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Start an email thread to one person from a shared cold inbox (DEV-3672). Every field is nullable so a missing one\nanswers 400 on its own field instead of a model-binding error."
      },
      "CreateTrackingLinkRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "nullable": true
          },
          "textValue": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateTranslationRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "Plain text to translate, at most 8,000 characters. Line breaks are kept.",
            "nullable": true
          },
          "targetLanguage": {
            "type": "string",
            "description": "Lowercase ISO 639-1 code of the language to translate into, such as `en`.",
            "nullable": true
          },
          "messageId": {
            "type": "string",
            "description": "Optional `msg_` id of the message the text comes from. An email message caches the result on itself, so\nthe next call for the same language is answered from it; a LinkedIn message is accepted and not cached.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateTriggerRequest": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "signalType": {
            "type": "string",
            "nullable": true
          },
          "tier": {
            "type": "string",
            "nullable": true
          },
          "parameters": {
            "type": "string",
            "nullable": true
          },
          "audienceFilter": {
            "type": "string",
            "nullable": true
          },
          "cooldownMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "maxAgeMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "stopSourceSequence": {
            "type": "boolean",
            "nullable": true
          },
          "switchCampaignToTrigger": {
            "type": "boolean",
            "description": "Opt-in, default false. A Batch campaign is switched to Trigger mode in the same transaction as the\ndefinition insert, so a failed create leaves it in Batch. Ignored for LinkedIn signals.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreateWebhookEndpointRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "app": {
            "type": "string",
            "description": "`zapier`, `make` or `n8n`. Omitted: taken from the URL host when it is a known catch-hook host.",
            "nullable": true
          },
          "campaignIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Deliver only events of these workspace campaigns. Omitted or empty: every campaign.",
            "nullable": true
          },
          "classifications": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Deliver only events with these reply classifications (snake_case, as in `reply.classified`). Omitted or empty: every one.",
            "nullable": true
          },
          "isBatched": {
            "type": "boolean",
            "description": "Receive the high-volume event types as batches. Default false.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "url": "https://hooks.example.com/kenso/replies",
          "events": [
            "reply.classified"
          ],
          "description": "Interested replies into our CRM",
          "campaignIds": [
            4821
          ],
          "classifications": [
            "interested"
          ],
          "isBatched": false
        }
      },
      "CreditAutoTopUpModel": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "thresholdCredits": {
            "type": "integer",
            "description": "Buy a pack when available credits drop below this many credits.",
            "format": "int32"
          },
          "packCredits": {
            "type": "integer",
            "description": "Credits bought per top-up, a multiple of 1,000.",
            "format": "int32"
          },
          "lastError": {
            "type": "string",
            "description": "Why the last automatic purchase failed. Omitted when it did not fail.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Opt-in rule that buys a credit pack when available credits drop below a threshold."
      },
      "CreditBalanceModel": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "description": "Always `credit_balance`.",
            "nullable": true
          },
          "balanceMillicredits": {
            "type": "integer",
            "description": "Open grants minus debt.",
            "format": "int64"
          },
          "includedMillicredits": {
            "type": "integer",
            "description": "Remaining plan-included credits (they expire). Billing permission only.",
            "format": "int64",
            "nullable": true
          },
          "purchasedMillicredits": {
            "type": "integer",
            "description": "Remaining purchased, granted and other non-expiring credits. Billing permission only.",
            "format": "int64",
            "nullable": true
          },
          "bonusMillicredits": {
            "type": "integer",
            "description": "Remaining Bonus credits: a credit promotion's monthly credits (the EWOR offer). Part of the balance, not of\n            `purchasedMillicredits`. They are spent before the included credits, expire at the end of their billing month\n            and cannot pay for Kenso inboxes or domains. 0 when none.",
            "format": "int64"
          },
          "bonusExpiresAt": {
            "type": "string",
            "description": "When the earliest remaining Bonus credits expire. Omitted when none are left.",
            "format": "date-time",
            "nullable": true
          },
          "bonusPromotion": {
            "$ref": "#/components/schemas/CreditBonusPromotionModel"
          },
          "debtMillicredits": {
            "type": "integer",
            "description": "Post-paid usage no grant has covered yet. The next grant repays it first. Billing permission only.",
            "format": "int64",
            "nullable": true
          },
          "reservedMonthlyMillicredits": {
            "type": "integer",
            "description": "Monthly cost of the active Kenso inboxes, domains and LinkedIn accounts, held back for infra. Billing\n            permission only.",
            "format": "int64",
            "nullable": true
          },
          "availableMillicredits": {
            "type": "integer",
            "description": "What data and AI work may spend: balance minus the monthly infra reservation.",
            "format": "int64"
          },
          "inboxDomainEligibleMillicredits": {
            "type": "integer",
            "description": "What can pay for Kenso inboxes and domains: the balance minus free and bonus credits, which cannot. Equal\n            to the balance when the workspace is exempt or Kenso allowed its free credits for them.",
            "format": "int64"
          },
          "includedExpiresAt": {
            "type": "string",
            "description": "When the earliest remaining included credits expire. Omitted when none are left. Billing permission only.",
            "format": "date-time",
            "nullable": true
          },
          "monthlyIncludedCredits": {
            "type": "integer",
            "description": "Credits the plan grants each billing month.",
            "format": "int32"
          },
          "usdPerCredit": {
            "type": "string",
            "description": "Price of one credit in USD, as a decimal string: `\"0.02\"`.",
            "nullable": true
          },
          "exempt": {
            "type": "boolean",
            "description": "True when the workspace is never charged for credits (charges are recorded, not debited)."
          },
          "creditState": {
            "type": "string",
            "description": "`healthy`, `low` (under 500 credits available) or `out` (data and AI work cannot start:\n            nothing available, or a white-label child cap is used up; sending and warmup keep running). Exempt\n            workspaces are always `healthy`.",
            "nullable": true
          },
          "exhaustedAt": {
            "type": "string",
            "description": "When available credits last dropped to zero or below. Omitted while credits are available.",
            "format": "date-time",
            "nullable": true
          },
          "grandfatheredUntil": {
            "type": "string",
            "description": "Until when a legacy plan keeps its grandfathered allowance. Omitted when not grandfathered. Billing\n            permission only.",
            "format": "date-time",
            "nullable": true
          },
          "sends": {
            "$ref": "#/components/schemas/CreditSendsModel"
          },
          "builds": {
            "$ref": "#/components/schemas/CreditBuildsModel"
          },
          "autoTopUp": {
            "$ref": "#/components/schemas/CreditAutoTopUpModel"
          },
          "reservedItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditReservedItemModel"
            },
            "description": "Active monthly infra items by action, in action order. Empty when there are none. Billing permission\n            only.",
            "nullable": true
          },
          "pendingCreditPurchases": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditPendingPurchaseModel"
            },
            "description": "Credit packs and auto top-ups paid by bank debit whose payment is still processing, oldest first.\n            Their credits are not in the balance yet; they are added when the payment clears. Empty when there are none.\n            Billing permission only.",
            "nullable": true
          },
          "unpaidRenewals": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditUnpaidRenewalModel"
            },
            "description": "Kenso inboxes, domains and LinkedIn accounts whose monthly renewal could not be paid in credits, by\n            resource type and the time they went unpaid, oldest first. Empty when every renewal is paid. Billing permission\n            only.",
            "nullable": true
          },
          "launchOffer": {
            "$ref": "#/components/schemas/CreditLaunchOfferModel"
          }
        },
        "additionalProperties": false,
        "description": "Credit balance of the workspace's billing account (DEV-1544). Every amount is millicredits\n(1 credit = 1,000 millicredits = $0.02). A white-label child sees its master's pooled balance.\nThe billing details (included, purchased, debt, reserved, grandfathering, auto top-up, pending purchases and\nunpaid renewals) are omitted unless the caller has the billing permission in the workspace (DEV-1654)."
      },
      "CreditBonusPromotionModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "The offer code, uppercase: `EWOR`.",
            "nullable": true
          },
          "monthlyCredits": {
            "type": "integer",
            "description": "Bonus credits granted each billing month.",
            "format": "int32"
          },
          "endsAt": {
            "type": "string",
            "description": "Exclusive: no Bonus credits for a billing month that starts at or after it.",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A live credit promotion (DEV-3225): `monthlyCredits` Bonus credits each billing month that starts before\n            `endsAt`, on top of the plan's included credits."
      },
      "CreditBuildsModel": {
        "type": "object",
        "properties": {
          "freeRemainingThisPeriod": {
            "type": "integer",
            "description": "Free campaign builds left this billing month (paid plans get one per month).",
            "format": "int32"
          },
          "overrunAvailable": {
            "type": "boolean",
            "description": "Whether a build that runs out of credits may still finish this billing month (once per month)."
          }
        },
        "additionalProperties": false
      },
      "CreditEstimateInfraItemRequest": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "description": "`ken_inbox_monthly`, `prewarmed_inbox`, `azure_domain_monthly`,\n            `smtp_domain_monthly`, `linkedin_account_monthly` or `domain_registration`.",
            "nullable": true
          },
          "quantity": {
            "type": "integer",
            "description": "1-1,000 (default 1).",
            "format": "int32",
            "nullable": true
          },
          "registrarPriceUsd": {
            "type": "number",
            "description": "Registrar price in USD for `domain_registration` (required there), above 0 and at most 1,000.",
            "format": "double",
            "nullable": true
          },
          "renewalPriceUsd": {
            "type": "number",
            "description": "Renewal price in USD for `domain_registration`, above 0 and at most 1,000.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreditEstimateLineModel": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "nullable": true
          },
          "units": {
            "type": "integer",
            "format": "int64"
          },
          "millicredits": {
            "type": "integer",
            "format": "int64"
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreditEstimateModel": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "description": "Always `credit_estimate`.",
            "nullable": true
          },
          "totalMillicredits": {
            "type": "integer",
            "description": "Credits needed now (infra counts its first month upfront).",
            "format": "int64"
          },
          "monthlyRecurringMillicredits": {
            "type": "integer",
            "description": "Credits the purchase adds to the monthly infra reservation. 0 for campaigns, builds and accounts.",
            "format": "int64"
          },
          "lines": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditEstimateLineModel"
            },
            "nullable": true
          },
          "availableMillicredits": {
            "type": "integer",
            "description": "Credits the estimate is measured against: available credits for campaigns, builds and accounts, the\n            whole balance for infra.",
            "format": "int64"
          },
          "sufficient": {
            "type": "boolean",
            "description": "Whether the workspace can cover the estimate now (always true when exempt)."
          },
          "freeBuild": {
            "type": "boolean",
            "description": "Build estimates only: whether the free monthly build covers it.",
            "nullable": true
          },
          "inboxDomainEligibleMillicredits": {
            "type": "integer",
            "description": "Infra estimates only: the credits that may pay the inbox and domain lines (the balance minus free and\n            bonus credits, which cannot). `sufficient` is false when these lines cost more, even when\n            `availableMillicredits` covers the total.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreditLaunchOfferModel": {
        "type": "object",
        "properties": {
          "startsAt": {
            "type": "string",
            "description": "First free instant.",
            "format": "date-time"
          },
          "endsAt": {
            "type": "string",
            "description": "Exclusive end: the last free day is the UTC day before it.",
            "format": "date-time"
          },
          "used": {
            "type": "integer",
            "description": "Lookups the offer counted for this workspace in the window, found or not.",
            "format": "int32"
          },
          "limit": {
            "type": "integer",
            "description": "The fair use limit: free lookups per workspace for the whole window.",
            "format": "int32"
          },
          "stoppedAt": {
            "type": "string",
            "description": "When the workspace reached the limit and the offer stopped for it. Omitted while the offer runs.",
            "format": "date-time",
            "nullable": true
          },
          "stoppedReason": {
            "type": "string",
            "description": "`fair_use` once the offer stopped for this workspace. Omitted while the offer runs.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Launch offer window (DEV-3006) and its fair use count (DEV-3326)."
      },
      "CreditLedgerEntryModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "action": {
            "type": "string",
            "description": "Credit action, e.g. `email_found`, `campaign_build`, `grant`, `refund`.",
            "nullable": true
          },
          "units": {
            "type": "integer",
            "description": "Units the line is for (contacts, sends, inboxes). Omitted for token-priced and bookkeeping lines.",
            "format": "int32",
            "nullable": true
          },
          "millicredits": {
            "type": "integer",
            "description": "Signed millicredits.",
            "format": "int64"
          },
          "reason": {
            "type": "string",
            "description": "`charge`, `release`, `settle`, `add_on`, `rebaseline`, `write_off`, `expire`,\n            `launch_offer` (a charge the launch offer waived, recorded at no cost), `email_pool_hit` (emails Kenso's shared\n            pool gave for free, recorded at no cost; `units` counts the emails).",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "workspaceId": {
            "type": "integer",
            "description": "The workspace that caused the line (a white-label child on its master's ledger).",
            "format": "int64"
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "shadow": {
            "type": "boolean",
            "description": "True when the workspace is exempt: the cost was recorded but not debited."
          },
          "category": {
            "type": "string",
            "description": "`infrastructure`, `ai`, `data`, `sending`, `calling` or `added_expired`\n            (grants, expiries and manual adjustments). A refund or write-off is in its charge's category. Clients tolerate\n            unknown values.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One credit ledger line. Charges are positive; grants are positive with reason `add_on`;\n            refunds, write-offs and expiries are negative."
      },
      "CreditLimitOverrideModel": {
        "type": "object",
        "properties": {
          "monthlyLimit": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreditPendingPurchaseModel": {
        "type": "object",
        "properties": {
          "credits": {
            "type": "integer",
            "description": "Whole credits added once the payment clears.",
            "format": "int32"
          },
          "amountUsd": {
            "type": "number",
            "description": "What the purchase charges, in USD.",
            "format": "double"
          },
          "kind": {
            "type": "string",
            "description": "`auto_top_up` or `pack`. Clients tolerate unknown values.",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A credit purchase whose payment is still processing."
      },
      "CreditRateCardItemModel": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "nullable": true
          },
          "unit": {
            "type": "string",
            "description": "What one unit is: `valid_email`, `contact_row`, `usd_model_spend`, `send`,\n            `inbox`, `domain`, `registrar_usd`, `linkedin_account`, `account`,\n            `studio_page`, `page`, `search_page`, `place_open`.",
            "nullable": true
          },
          "unitSize": {
            "type": "integer",
            "description": "Quantity the price is usually quoted for, e.g. 1,000 contact rows.",
            "format": "int32"
          },
          "millicreditsPerUnit": {
            "type": "integer",
            "description": "Millicredits per ONE unit. Domain rows apply to `ceil(registrarUsd x 1.03) + 1` whole dollars.",
            "format": "int64"
          },
          "billing": {
            "type": "string",
            "description": "`per_use`, `monthly`, `one_time` or `yearly`.",
            "nullable": true
          },
          "note": {
            "type": "string",
            "description": "Extra pricing detail, e.g. what costs more and when the action costs nothing. Omitted when null.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreditRateCardModel": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "description": "Always `credit_rate_card`.",
            "nullable": true
          },
          "usdPerCredit": {
            "type": "string",
            "nullable": true
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditRateCardItemModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CreditReservedItemModel": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "description": "Credit action: `ken_inbox_monthly`, `azure_domain_monthly`, `smtp_domain_monthly`,\n            `linkedin_account_monthly`. Clients tolerate unknown values.",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "monthlyMillicredits": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "CreditSavingsItemModel": {
        "type": "object",
        "properties": {
          "item": {
            "$ref": "#/components/schemas/FreeWorkItemEnum"
          },
          "units": {
            "type": "integer",
            "format": "int64"
          },
          "unitPriceUsdMicros": {
            "type": "integer",
            "description": "Clay's price of one unit in millionths of a dollar. Absent for `launch_offer` when it mixes email finds and enrichments.",
            "format": "int64",
            "nullable": true
          },
          "valueUsdCents": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "CreditSavingsLifetimeModel": {
        "type": "object",
        "properties": {
          "since": {
            "type": "string",
            "description": "The workspace's first day of free work. Absent before its first.",
            "format": "date",
            "nullable": true
          },
          "totalUsdCents": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "CreditSavingsModel": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "First UTC day, inclusive.",
            "format": "date"
          },
          "to": {
            "type": "string",
            "description": "Last UTC day, inclusive.",
            "format": "date"
          },
          "priceSource": {
            "type": "string",
            "description": "Whose prices value the work: always `clay`.",
            "nullable": true
          },
          "pricesCheckedOn": {
            "type": "string",
            "description": "When Clay's prices were last checked.",
            "format": "date"
          },
          "totalUsdCents": {
            "type": "integer",
            "format": "int64"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditSavingsItemModel"
            },
            "description": "The six priced items in card order, then `launch_offer` when the launch offer covered work.",
            "nullable": true
          },
          "lifetime": {
            "$ref": "#/components/schemas/CreditSavingsLifetimeModel"
          }
        },
        "additionalProperties": false,
        "description": "`credit-savings.get` (DEV-5976, Free with Ken): what Ken did free for the workspace in a window, priced at Clay's\n            rates. Ken.Scraper.API.Canonical.CreditSavingsModel.TotalUsdCents is the sum of Ken.Scraper.API.Canonical.CreditSavingsModel.Items, each the sum of its activity rows."
      },
      "CreditSavingsRowModel": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "item": {
            "$ref": "#/components/schemas/FreeWorkItemEnum"
          },
          "campaignId": {
            "type": "integer",
            "description": "Absent for work outside a campaign.",
            "format": "int64",
            "nullable": true
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "units": {
            "type": "integer",
            "format": "int64"
          },
          "valueUsdCents": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false,
        "description": "`credit-savings-rows.list`: one item's free units on one UTC day for one campaign."
      },
      "CreditSendsModel": {
        "type": "object",
        "properties": {
          "includedPerPeriod": {
            "type": "integer",
            "description": "Sends included per billing month. Omitted when sends are unlimited.",
            "format": "int32",
            "nullable": true
          },
          "usedThisPeriod": {
            "type": "integer",
            "format": "int32"
          },
          "periodStart": {
            "type": "string",
            "format": "date-time"
          },
          "periodEnd": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CreditSpendCategoryModel": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "description": "`infrastructure`, `ai`, `data`, `sending` or `calling`.",
            "nullable": true
          },
          "millicredits": {
            "type": "integer",
            "description": "Net millicredits charged: charges minus refunds and overrun write-offs. Can be negative when a refund\n            lands in a later period than its charge.",
            "format": "int64"
          },
          "amount": {
            "$ref": "#/components/schemas/MoneyModel"
          },
          "lineCount": {
            "type": "integer",
            "description": "Ledger lines in the category, not-charged (shadow) lines included.",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CreditSpendModel": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "description": "Always `credit_spend`.",
            "nullable": true
          },
          "period": {
            "type": "string",
            "description": "`billing_month`, `since_signup` (what `billing_month` resolves to on Free),\n            `last_30_days` or `all_time`.",
            "nullable": true
          },
          "from": {
            "type": "string",
            "description": "Inclusive start. Omitted for `all_time`.",
            "format": "date-time",
            "nullable": true
          },
          "to": {
            "type": "string",
            "description": "Exclusive end: the billing month's end, else now.",
            "format": "date-time"
          },
          "totalMillicredits": {
            "type": "integer",
            "description": "The spend categories' millicredits added up.",
            "format": "int64"
          },
          "totalAmount": {
            "$ref": "#/components/schemas/MoneyModel"
          },
          "categories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CreditSpendCategoryModel"
            },
            "description": "`infrastructure`, `ai`, `data`, `sending` and `calling` (DEV-3327), always all\n            five in that order.",
            "nullable": true
          },
          "addedExpiredLineCount": {
            "type": "integer",
            "description": "Grant, expiry and manual adjustment lines in the period (the \"Added and expired\" chip).",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "What the workspace spent per category in a period (DEV-1784). Spend is net and leaves out shadow (not charged)\nlines; line counts include them."
      },
      "CreditUnpaidRenewalModel": {
        "type": "object",
        "properties": {
          "resourceType": {
            "type": "string",
            "description": "`inbox`, `domain` or `linkedin_account`. Clients tolerate unknown values.",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "unpaidSince": {
            "type": "string",
            "description": "When the renewal charge first failed for lack of credits.",
            "format": "date-time"
          },
          "deleteAfter": {
            "type": "string",
            "description": "When the items may be deleted if still unpaid (`unpaidSince` plus 30 days by default). The\n            hourly renewal job deletes them on its first run at or after this time.",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "Monthly infra items whose renewal went unpaid at the same time. The renewal is retried every hour, so\n            buying credits pays it; items still unpaid at Ken.Scraper.API.Canonical.CreditUnpaidRenewalModel.DeleteAfter are deleted."
      },
      "CrmAuthorizeModel": {
        "type": "object",
        "properties": {
          "authorizeUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmConnectionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "pausedReason": {
            "type": "string",
            "nullable": true
          },
          "externalAccountName": {
            "type": "string",
            "nullable": true
          },
          "instanceUrl": {
            "type": "string",
            "nullable": true
          },
          "connectedAsEmail": {
            "type": "string",
            "nullable": true
          },
          "connectedAt": {
            "type": "string",
            "format": "date-time"
          },
          "disconnectedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastImportStartedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastImportCompletedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastInboundAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastOutboundAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "lastErrorAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "syncObjects": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/CrmSyncObjectModel"
            },
            "nullable": true
          },
          "settings": {
            "$ref": "#/components/schemas/CrmSettingsModel"
          },
          "capabilities": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmFieldMapModel": {
        "type": "object",
        "properties": {
          "mappings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmFieldMappingModel"
            },
            "nullable": true
          },
          "kenFields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmKenFieldModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmFieldMappingBody": {
        "type": "object",
        "properties": {
          "kenField": {
            "type": "string",
            "nullable": true
          },
          "crmField": {
            "type": "string",
            "nullable": true
          },
          "direction": {
            "type": "string",
            "nullable": true
          },
          "isEnabled": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmFieldMappingModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "objectType": {
            "type": "string",
            "nullable": true
          },
          "kenField": {
            "type": "string",
            "nullable": true
          },
          "kenFieldLabel": {
            "type": "string",
            "nullable": true
          },
          "crmField": {
            "type": "string",
            "nullable": true
          },
          "direction": {
            "type": "string",
            "nullable": true
          },
          "isEnabled": {
            "type": "boolean"
          },
          "isDefault": {
            "type": "boolean"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CrmFieldModel": {
        "type": "object",
        "properties": {
          "apiName": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "dataType": {
            "type": "string",
            "nullable": true
          },
          "isCustom": {
            "type": "boolean"
          },
          "isReadOnly": {
            "type": "boolean"
          },
          "isRequiredOnCreate": {
            "type": "boolean"
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmPicklistOptionModel"
            },
            "nullable": true
          },
          "isKenField": {
            "type": "boolean"
          },
          "exists": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "CrmFieldUpdateSampleModel": {
        "type": "object",
        "properties": {
          "entityRef": {
            "type": "string",
            "nullable": true
          },
          "objectType": {
            "type": "string",
            "nullable": true
          },
          "crmField": {
            "type": "string",
            "nullable": true
          },
          "kenField": {
            "type": "string",
            "nullable": true
          },
          "from": {
            "type": "string",
            "nullable": true
          },
          "to": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmFieldUpdatesModel": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "recordsChecked": {
            "type": "integer",
            "format": "int32"
          },
          "complete": {
            "type": "boolean"
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmFieldUpdateSampleModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmImportModel": {
        "type": "object",
        "properties": {
          "startedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CrmInboundPeopleFilterBody": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "nullable": true
          },
          "op": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmInboundPeopleFilterModel": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "nullable": true
          },
          "op": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmInboundPeopleModel": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmInboundPeopleFilterModel"
            },
            "nullable": true
          },
          "leadStatus": {
            "type": "string",
            "nullable": true
          },
          "defaultOwnerMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "enabledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmKenFieldModel": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "objectType": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "dataType": {
            "type": "string",
            "nullable": true
          },
          "fixedDirection": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmLinkedEntityModel": {
        "type": "object",
        "properties": {
          "entityType": {
            "type": "string",
            "nullable": true
          },
          "entityId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "entityKey": {
            "type": "string",
            "nullable": true
          },
          "entityRef": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmListModel": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "objectType": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isDynamic": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "CrmListSourceBody": {
        "type": "object",
        "properties": {
          "listExternalId": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "keepInSync": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmListSourceModel": {
        "type": "object",
        "properties": {
          "listExternalId": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "keepInSync": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "CrmOAuthCompletionModel": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "nullable": true
          },
          "returnPath": {
            "type": "string",
            "nullable": true
          },
          "connection": {
            "$ref": "#/components/schemas/CrmConnectionModel"
          }
        },
        "additionalProperties": false
      },
      "CrmObjectCountsModel": {
        "type": "object",
        "properties": {
          "companies": {
            "type": "integer",
            "format": "int32"
          },
          "contacts": {
            "type": "integer",
            "format": "int32"
          },
          "deals": {
            "type": "integer",
            "format": "int32"
          },
          "owners": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CrmPicklistOptionModel": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmPipelineModel": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "stages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmStageModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmPreviewModel": {
        "type": "object",
        "properties": {
          "matched": {
            "$ref": "#/components/schemas/CrmObjectCountsModel"
          },
          "read": {
            "$ref": "#/components/schemas/CrmObjectCountsModel"
          },
          "wouldCreate": {
            "$ref": "#/components/schemas/CrmWouldCreateModel"
          },
          "fieldUpdates": {
            "$ref": "#/components/schemas/CrmFieldUpdatesModel"
          },
          "unmatchedOwners": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmUnmatchedOwnerModel"
            },
            "nullable": true
          },
          "importCompletedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmRecordCountModel": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "format": "int32"
          },
          "linked": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CrmRecordModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "objectType": {
            "type": "string",
            "nullable": true
          },
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "externalSubtype": {
            "type": "string",
            "nullable": true
          },
          "externalUrl": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "domain": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "ownerExternalId": {
            "type": "string",
            "nullable": true
          },
          "lifecycle": {
            "type": "string",
            "nullable": true
          },
          "isOptedOut": {
            "type": "boolean"
          },
          "isCustomer": {
            "type": "boolean"
          },
          "hasOpenDeal": {
            "type": "boolean"
          },
          "lastRepActivityAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "crmUpdatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastSyncedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "crmDeletedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "mergedIntoExternalId": {
            "type": "string",
            "nullable": true
          },
          "snapshot": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "nullable": true
            },
            "nullable": true
          },
          "linked": {
            "$ref": "#/components/schemas/CrmLinkedEntityModel"
          }
        },
        "additionalProperties": false
      },
      "CrmSettingsModel": {
        "type": "object",
        "properties": {
          "createRecordsWhen": {
            "type": "string",
            "nullable": true
          },
          "salesforcePersonMode": {
            "type": "string",
            "nullable": true
          },
          "emailLogging": {
            "type": "string",
            "nullable": true
          },
          "pipelineExternalId": {
            "type": "string",
            "nullable": true
          },
          "stageMap": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "importDaily": {
            "type": "boolean"
          },
          "skipOpenOpportunities": {
            "type": "boolean"
          },
          "blockCustomers": {
            "type": "boolean"
          },
          "pauseOnRepActivityDays": {
            "type": "integer",
            "format": "int32"
          },
          "staticListPerCampaign": {
            "type": "boolean"
          },
          "listSources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmListSourceModel"
            },
            "nullable": true
          },
          "inboundPeople": {
            "$ref": "#/components/schemas/CrmInboundPeopleModel"
          }
        },
        "additionalProperties": false
      },
      "CrmStageModel": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "position": {
            "type": "integer",
            "format": "int32"
          },
          "category": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmSyncHealthModel": {
        "type": "object",
        "properties": {
          "connectionId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "pausedReason": {
            "type": "string",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "lastErrorAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastImportStartedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastImportCompletedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "importRunning": {
            "type": "boolean"
          },
          "lastInboundAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastOutboundAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "objects": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/CrmSyncObjectHealthModel"
            },
            "nullable": true
          },
          "queueDepth": {
            "type": "integer",
            "format": "int32"
          },
          "oldestPendingAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "needsAttentionCount": {
            "type": "integer",
            "format": "int32"
          },
          "inboundBacklog": {
            "type": "integer",
            "format": "int32"
          },
          "owners": {
            "$ref": "#/components/schemas/CrmRecordCountModel"
          }
        },
        "additionalProperties": false
      },
      "CrmSyncIssueModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "entityRef": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "attempts": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "CrmSyncObjectHealthModel": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "enabledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastInboundAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastOutboundAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "records": {
            "$ref": "#/components/schemas/CrmRecordCountModel"
          }
        },
        "additionalProperties": false
      },
      "CrmSyncObjectModel": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean"
          },
          "enabledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmSyncObjectPatch": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmUnmatchedOwnerModel": {
        "type": "object",
        "properties": {
          "externalId": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CrmWouldCreateModel": {
        "type": "object",
        "properties": {
          "contacts": {
            "type": "integer",
            "format": "int32"
          },
          "companies": {
            "type": "integer",
            "format": "int32"
          },
          "createRecordsWhen": {
            "type": "string",
            "nullable": true
          },
          "complete": {
            "type": "boolean"
          },
          "excludedLibraryContacts": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "CsvColumnMapping": {
        "type": "object",
        "properties": {
          "csvColumn": {
            "type": "string",
            "nullable": true
          },
          "targetField": {
            "type": "string",
            "nullable": true
          },
          "customVariableName": {
            "type": "string",
            "nullable": true
          },
          "useAsAiContext": {
            "type": "boolean",
            "nullable": true
          },
          "isRequiredForSending": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CurrentExperienceImportDTO": {
        "type": "object",
        "properties": {
          "companyId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "companyUrl": {
            "type": "string",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "companyEmployeeCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "startDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CustomVariableFilterDto": {
        "type": "object",
        "properties": {
          "variableKey": {
            "type": "string",
            "nullable": true
          },
          "operator": {
            "$ref": "#/components/schemas/CustomVariableFilterOperatorEnum"
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "CustomVariableFilterOperatorEnum": {
        "enum": [
          "Contains",
          "NotContains",
          "Equals",
          "NotEquals",
          "IsEmpty",
          "IsNotEmpty"
        ],
        "type": "string"
      },
      "CustomVariableModel": {
        "type": "object",
        "properties": {
          "variableKey": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "useAsAiContext": {
            "type": "boolean"
          },
          "isRequiredForSending": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "DataTypeEnum": {
        "enum": [
          0,
          1,
          2,
          3,
          4,
          5
        ],
        "type": "integer",
        "format": "int32"
      },
      "DateRange": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DeliverabilityAlertModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "`sending_paused`, `blocklisted`, `authentication_failing`, `dmarc_failing`,\n            `placement_spam`, `placement_low_inbox`, `complaint_rate`, `microsoft_tenant_ban`,\n            `sender_rejections`, `high_bounce_rate` or `recipient_refusals`. New codes may be added.",
            "nullable": true
          },
          "scope": {
            "type": "string",
            "description": "`domain` or `inbox`: the target the alert is about.",
            "nullable": true
          },
          "severity": {
            "type": "string",
            "description": "`warning` or `critical`.",
            "nullable": true
          },
          "message": {
            "type": "string",
            "description": "One plain sentence with the number.",
            "nullable": true
          },
          "action": {
            "type": "string",
            "description": "One sentence: what to do.",
            "nullable": true
          },
          "since": {
            "type": "string",
            "description": "When the signal was seen. Omitted when unknown.",
            "format": "date-time",
            "nullable": true
          },
          "until": {
            "type": "string",
            "description": "When the pause ends. Only on `sending_paused`.",
            "format": "date-time",
            "nullable": true
          },
          "rate": {
            "type": "number",
            "description": "The rate behind the alert, a fraction from 0 to 1. Omitted when no rate drives it.",
            "format": "double",
            "nullable": true
          },
          "threshold": {
            "type": "number",
            "description": "The threshold it crossed, a fraction from 0 to 1. Omitted when no rate drives it.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DeliverabilityGateDomainModel": {
        "type": "object",
        "properties": {
          "domainId": {
            "type": "integer",
            "description": "Managed domain id. Omitted for the address domain of mailboxes with no managed domain (OAuth and own SMTP);\nfree-mail providers such as gmail.com get no domain row.",
            "format": "int64",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "nullable": true
          },
          "inboxCount": {
            "type": "integer",
            "description": "Inboxes on the domain that sent in the window.",
            "format": "int32"
          },
          "sentCount": {
            "type": "integer",
            "format": "int32"
          },
          "bounceCount": {
            "type": "integer",
            "description": "Hard bounces in the window.",
            "format": "int32"
          },
          "bounceRate": {
            "type": "number",
            "description": "bounceCount / sentCount, a fraction from 0 to 1.",
            "format": "double"
          },
          "verdict": {
            "type": "string",
            "description": "`over`, `watch` (at or above 80% of the threshold) or `ok`.",
            "nullable": true
          },
          "isSmallSample": {
            "type": "boolean",
            "description": "Fewer sends than `domainGate.minSends`: the row cannot be over yet, whatever its rate."
          }
        },
        "additionalProperties": false
      },
      "DeliverabilityGateInboxModel": {
        "type": "object",
        "properties": {
          "inboxId": {
            "type": "integer",
            "format": "int64"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "description": "Managed domain id. Omitted for a mailbox with no managed domain.",
            "format": "int64",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "nullable": true
          },
          "sentCount": {
            "type": "integer",
            "format": "int32"
          },
          "bounceCount": {
            "type": "integer",
            "description": "Hard bounces in the window.",
            "format": "int32"
          },
          "bounceRate": {
            "type": "number",
            "description": "bounceCount / sentCount, a fraction from 0 to 1.",
            "format": "double"
          },
          "verdict": {
            "type": "string",
            "description": "`over`, `watch` (at or above 80% of the threshold) or `ok`.",
            "nullable": true
          },
          "isSmallSample": {
            "type": "boolean",
            "description": "Fewer sends than `inboxGate.minSends`: the row cannot be over yet, whatever its rate."
          }
        },
        "additionalProperties": false
      },
      "DeliverabilityGateModel": {
        "type": "object",
        "properties": {
          "threshold": {
            "type": "number",
            "description": "Hard-bounce rate a row must be strictly above to be over, as a fraction from 0 to 1.",
            "format": "double"
          },
          "minSends": {
            "type": "integer",
            "description": "Fewest sends in the window before a row can be over.",
            "format": "int32"
          },
          "minBounces": {
            "type": "integer",
            "description": "Fewest hard bounces in the window before a row can be over.",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "DeliverabilityGatesModel": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "windowHours": {
            "type": "integer",
            "description": "Hours of sends and hard bounces the rows count: 24.",
            "format": "int32"
          },
          "isEnforced": {
            "type": "boolean",
            "description": "True when the sequencer blocks inboxes and pauses campaigns on these gates; false when it only records them."
          },
          "enforcedWindowHours": {
            "type": "integer",
            "description": "Hours of the rolling window the sequencer itself judges an inbox or campaign over.",
            "format": "int32"
          },
          "domainGate": {
            "$ref": "#/components/schemas/DeliverabilityGateModel"
          },
          "inboxGate": {
            "$ref": "#/components/schemas/DeliverabilityGateModel"
          },
          "domainCount": {
            "type": "integer",
            "description": "Domains that sent in the window, before `limit`.",
            "format": "int32"
          },
          "inboxCount": {
            "type": "integer",
            "description": "Inboxes that sent in the window, before `limit`.",
            "format": "int32"
          },
          "domains": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeliverabilityGateDomainModel"
            },
            "description": "Worst first: over, then watch, then ok, each by bounce rate.",
            "nullable": true
          },
          "inboxes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeliverabilityGateInboxModel"
            },
            "description": "Worst first: over, then watch, then ok, each by bounce rate.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-5210: the bounce gates the sequencer enforces, applied to the last 24 hours."
      },
      "DeliverabilityMetricsModel": {
        "type": "object",
        "properties": {
          "sentCount": {
            "type": "integer",
            "format": "int64"
          },
          "replyCount": {
            "type": "integer",
            "format": "int64"
          },
          "bounceCount": {
            "type": "integer",
            "format": "int64"
          },
          "clickCount": {
            "type": "integer",
            "format": "int64"
          },
          "replyRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "bounceRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "clickRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "inboxCount": {
            "type": "integer",
            "format": "int32"
          },
          "activeInboxCount": {
            "type": "integer",
            "format": "int32"
          },
          "domainCount": {
            "type": "integer",
            "format": "int32"
          },
          "inboxesPerDomain": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "healthyInboxCount": {
            "type": "integer",
            "format": "int32"
          },
          "lowActivityInboxCount": {
            "type": "integer",
            "format": "int32"
          },
          "inactiveInboxCount": {
            "type": "integer",
            "format": "int32"
          },
          "complaintCount": {
            "type": "integer",
            "description": "Spam complaints in the window. Omitted when the complaint data could not be read.",
            "format": "int64",
            "nullable": true
          },
          "complaintRate": {
            "type": "number",
            "description": "Complaints / sent, a fraction from 0 to 1. Omitted when nothing was sent.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DeliverabilityModel": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "groupBy": {
            "type": "string",
            "nullable": true
          },
          "timeZone": {
            "type": "string",
            "nullable": true
          },
          "metrics": {
            "$ref": "#/components/schemas/DeliverabilityMetricsModel"
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeliverabilityRowModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DeliverabilityRowModel": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "inboxCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "sentCount": {
            "type": "integer",
            "format": "int64"
          },
          "replyCount": {
            "type": "integer",
            "format": "int64"
          },
          "bounceCount": {
            "type": "integer",
            "format": "int64"
          },
          "clickCount": {
            "type": "integer",
            "format": "int64"
          },
          "replyRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "bounceRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "clickRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "complaintCount": {
            "type": "integer",
            "description": "Spam complaints on a day or domain row. Omitted on inbox rows.",
            "format": "int64",
            "nullable": true
          },
          "oooCount": {
            "type": "integer",
            "description": "Out-of-office replies on a domain or inbox row. Omitted on day rows.",
            "format": "int64",
            "nullable": true
          },
          "oooRate": {
            "type": "number",
            "description": "Out-of-office replies / sent, a fraction from 0 to 1. Omitted on day rows and when nothing was sent.",
            "format": "double",
            "nullable": true
          },
          "reputation": {
            "type": "string",
            "description": "Domain and inbox rows: `paused` (an active Ken pause covers the row), `at_risk` (a critical alert),\n`watch` (a warning alert), `good` (no alert) or `unknown` (a signal could not be read, or there is\nno recent evidence). Omitted on day rows. It describes the state now: only the `complaint_rate` and\n`high_bounce_rate` alerts count the requested window.",
            "nullable": true
          },
          "alerts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DeliverabilityAlertModel"
            },
            "description": "Domain and inbox rows: plain-language alerts, empty when nothing is wrong. An inbox row also carries its\ndomain's alerts with `scope``domain`. New codes may be added. Omitted on day rows.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DomainBulkFailure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DomainBulkResult": {
        "type": "object",
        "properties": {
          "updatedCount": {
            "type": "integer",
            "format": "int32"
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainBulkFailure"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DomainDnsModel": {
        "type": "object",
        "properties": {
          "trackingStatus": {
            "type": "string",
            "nullable": true
          },
          "clickRateTrackingEnabled": {
            "type": "boolean"
          },
          "openPixelHostname": {
            "type": "string",
            "nullable": true
          },
          "openPixelStatus": {
            "type": "string",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DomainDnsRecordModel": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DomainHealthModel": {
        "type": "object",
        "properties": {
          "domainId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "blacklistStatus": {
            "type": "string",
            "nullable": true
          },
          "listedCount": {
            "type": "integer",
            "format": "int32"
          },
          "listedZones": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "spfStatus": {
            "type": "string",
            "nullable": true
          },
          "dkimStatus": {
            "type": "string",
            "nullable": true
          },
          "dmarcStatus": {
            "type": "string",
            "nullable": true
          },
          "mxStatus": {
            "type": "string",
            "nullable": true
          },
          "hasSpf": {
            "type": "boolean"
          },
          "hasDkim": {
            "type": "boolean"
          },
          "hasDmarc": {
            "type": "boolean"
          },
          "hasMx": {
            "type": "boolean"
          },
          "isChecked": {
            "type": "boolean"
          },
          "dkimSelector": {
            "type": "string",
            "nullable": true
          },
          "bounceRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "bounceStatus": {
            "type": "string",
            "nullable": true
          },
          "bounceCheckedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "bounceEmailCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bouncedEmailCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "inboxRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "spamRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "placementStatus": {
            "type": "string",
            "nullable": true
          },
          "placementCompletedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "infraguardStatus": {
            "type": "string",
            "nullable": true
          },
          "nameserverStatus": {
            "type": "string",
            "nullable": true
          },
          "nameservers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "sslStatus": {
            "type": "string",
            "nullable": true
          },
          "sslExpiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "ipAbuseScore": {
            "type": "integer",
            "description": "Stored AbuseIPDB score. Omitted when the check has none.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DomainModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "expirationDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "daysLeft": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isExpiring": {
            "type": "boolean"
          },
          "autoRenew": {
            "type": "boolean"
          },
          "autoRenewEligible": {
            "type": "boolean"
          },
          "registrar": {
            "type": "string",
            "nullable": true
          },
          "dnsProvider": {
            "type": "string",
            "nullable": true
          },
          "clickRateTrackingEnabled": {
            "type": "boolean"
          },
          "trackingDnsStatus": {
            "type": "string",
            "nullable": true
          },
          "maskingEnabled": {
            "type": "boolean"
          },
          "rampUpDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "rampUp": {
            "$ref": "#/components/schemas/DomainRampUpModel"
          },
          "redirectUrl404": {
            "type": "string",
            "nullable": true
          },
          "openPixelHostname": {
            "type": "string",
            "nullable": true
          },
          "openPixelStatus": {
            "type": "string",
            "nullable": true
          },
          "campaignPixelHost": {
            "$ref": "#/components/schemas/CampaignPixelHostModel"
          },
          "catchAllEmail": {
            "type": "string",
            "nullable": true
          },
          "hasError": {
            "type": "boolean"
          },
          "statusReason": {
            "type": "string",
            "nullable": true
          },
          "isPrimary": {
            "type": "boolean",
            "description": "True when this is one of the workspace's own domains (its email domain or a domain listed under\nSettings > Company), the domains members' primary inboxes sit on (same rule as `isPrimary` on an inbox).\nDerived on read (DEV-2026, DEV-3886)."
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "retirement": {
            "$ref": "#/components/schemas/DomainRetirementModel"
          },
          "replacedBy": {
            "$ref": "#/components/schemas/DomainReplacementModel"
          }
        },
        "additionalProperties": false
      },
      "DomainNameserverCheckModel": {
        "type": "object",
        "properties": {
          "domainId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "zoneStatus": {
            "type": "string",
            "nullable": true
          },
          "activated": {
            "type": "boolean"
          },
          "expectedNameservers": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "waitingForCredits": {
            "type": "boolean",
            "description": "The zone is active but activation waits until the workspace can pay the first month of the pending mailboxes."
          },
          "requiredMillicredits": {
            "type": "integer",
            "description": "Set with Ken.Scraper.API.Canonical.DomainNameserverCheckModel.WaitingForCredits: the first month of the pending mailboxes.",
            "format": "int64",
            "nullable": true
          },
          "availableMillicredits": {
            "type": "integer",
            "description": "Set with Ken.Scraper.API.Canonical.DomainNameserverCheckModel.WaitingForCredits: the workspace's total balance.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "DomainRampUpModel": {
        "type": "object",
        "properties": {
          "days": {
            "type": "integer",
            "description": "Length of the ramp-up in days. 0 means the domain does not ramp up.",
            "format": "int32"
          },
          "dayIndex": {
            "type": "integer",
            "description": "Today's day of the ramp-up, 1 to Ken.Scraper.API.Canonical.DomainRampUpModel.Days, counted in UTC calendar days from when the ramp\nstarted (day 1 before it starts). Stays at Ken.Scraper.API.Canonical.DomainRampUpModel.Days once the ramp-up is over; 0 when\nKen.Scraper.API.Canonical.DomainRampUpModel.Days is 0.",
            "format": "int32"
          },
          "isComplete": {
            "type": "boolean",
            "description": "The inboxes on the domain send at their full daily limit: the ramp-up is over, the domain has none, or\nramp-up is switched off."
          }
        },
        "additionalProperties": false
      },
      "DomainReplacementModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The domain that replaced another (DEV-6706)."
      },
      "DomainRetirementModel": {
        "type": "object",
        "properties": {
          "state": {
            "type": "string",
            "description": "`pending` (opening; Cloudflare not confirmed, retried every 15 minutes), `applied` (replies are caught),\n            `release_pending` (ending; Cloudflare not confirmed), `released` (ended) or `failed` (ended without\n            applying: the zone left Kenso's Cloudflare account).",
            "nullable": true
          },
          "captureUntil": {
            "type": "string",
            "description": "UTC end of the capture window.",
            "format": "date-time"
          },
          "releasedAt": {
            "type": "string",
            "description": "UTC time the window ended; omitted while it is open.",
            "format": "date-time",
            "nullable": true
          },
          "renewalEndsWindowEarly": {
            "type": "boolean",
            "description": "True while the window is open, auto-renew is off and the registration expires before Ken.Scraper.API.Canonical.DomainRetirementModel.CaptureUntil:\nthe domain can lapse, and a new owner would get the replies."
          }
        },
        "additionalProperties": false,
        "description": "A retired domain's capture window (DEV-3197): its mail goes to Kenso's reply catch so replies to past sends still\narrive, until Ken.Scraper.API.Canonical.DomainRetirementModel.CaptureUntil."
      },
      "DomainWebsiteHostnameModel": {
        "type": "object",
        "properties": {
          "hostname": {
            "type": "string",
            "nullable": true
          },
          "attachPath": {
            "type": "string",
            "description": "`worker_route` or `custom_hostname`; null when the domain cannot show the page.",
            "nullable": true
          },
          "dnsWriter": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`detached`, `attaching`, `active`, `detaching` or `failed`.",
            "nullable": true
          },
          "sslStatus": {
            "type": "string",
            "nullable": true
          },
          "unsupportedReason": {
            "type": "string",
            "description": "Why this hostname cannot show the page; null when it can.",
            "nullable": true
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "description": "Why Kenso's last attach or detach of this hostname failed, as one short fixed sentence with no trailing period (never\nthe provider's own text); null when the last attempt did not fail.",
            "nullable": true
          },
          "stopped": {
            "type": "boolean",
            "description": "True when Kenso stopped retrying after repeated failures. It starts again once the domain's answer or its DNS\nclassification changes: switching the domain to redirect and back restarts it."
          }
        },
        "additionalProperties": false
      },
      "DomainWebsiteModel": {
        "type": "object",
        "properties": {
          "domainId": {
            "type": "integer",
            "format": "int64"
          },
          "mode": {
            "type": "string",
            "description": "`unset` (nobody answered: today's redirect), `redirect` or `page`.",
            "nullable": true
          },
          "currentVersionId": {
            "type": "integer",
            "description": "The workspace's live page version, null while no page was ever published.",
            "format": "int64",
            "nullable": true
          },
          "hostnames": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/DomainWebsiteHostnameModel"
            },
            "description": "Apex first, then `www`. Empty until Kenso has checked the domain.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What people see on one domain (DEV-6032)."
      },
      "DropVoicemailRequest": {
        "type": "object",
        "properties": {
          "voicemailId": {
            "type": "integer",
            "description": "One of your greetings; absent drops your oldest.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "POST /v1/calling/calls/{callId}/voicemail-drop body (Dialer 08). The body may be absent."
      },
      "DuplicateCampaignBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "includeContacts": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "EmailCopyGradeCriterionModel": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "score": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "yes": {
            "type": "boolean",
            "nullable": true
          },
          "probability": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailCopyGradeGeneralModel": {
        "type": "object",
        "properties": {
          "score": {
            "type": "number",
            "format": "double"
          },
          "label": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailCopyGradeModel": {
        "type": "object",
        "properties": {
          "channel": {
            "type": "string",
            "description": "The channel that was graded: `email`, `linkedin_connection` or `linkedin_message`.",
            "nullable": true
          },
          "copyHash": {
            "type": "string",
            "nullable": true
          },
          "gradedAt": {
            "type": "string",
            "format": "date-time"
          },
          "fromSavedGrade": {
            "type": "boolean"
          },
          "overall": {
            "$ref": "#/components/schemas/EmailCopyGradeOverallModel"
          },
          "general": {
            "$ref": "#/components/schemas/EmailCopyGradeGeneralModel"
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailCopyGradeQuestionModel"
            },
            "nullable": true
          },
          "criteria": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailCopyGradeCriterionModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailCopyGradeOverallModel": {
        "type": "object",
        "properties": {
          "score": {
            "type": "number",
            "format": "double"
          },
          "band": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "alarmQuestionIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailCopyGradeQuestionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "blurb": {
            "type": "string",
            "nullable": true
          },
          "alarm": {
            "type": "boolean"
          },
          "score": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "yes": {
            "type": "boolean",
            "nullable": true
          },
          "probability": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailCopyLintModel": {
        "type": "object",
        "properties": {
          "passed": {
            "type": "boolean",
            "description": "True when no rule failed at `reject` severity."
          },
          "rejectCount": {
            "type": "integer",
            "format": "int32"
          },
          "flagCount": {
            "type": "integer",
            "format": "int32"
          },
          "wordCount": {
            "type": "integer",
            "description": "Words in the whole body, greeting through signature and PS.",
            "format": "int32"
          },
          "staticWordCount": {
            "type": "integer",
            "description": "Words of prose and CTA, without the greeting, AI variable lines, signature or PS.",
            "format": "int32"
          },
          "linkCount": {
            "type": "integer",
            "format": "int32"
          },
          "firstLine": {
            "type": "string",
            "description": "The static opener the first-line rules read. Absent on a follow-up or when the opener is an AI variable.",
            "nullable": true
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailCopyLintRuleModel"
            },
            "description": "Every rule, always in the same order.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailCopyLintRuleModel": {
        "type": "object",
        "properties": {
          "rule": {
            "type": "string",
            "description": "`subject_length`, `body_words`, `static_words`, `em_dash`, `links`, `placeholders`,\n            `merge_fields`, `blank_merge_fields`, `ai_variables`, `first_line_fact`,\n            `first_line_first_person`, `first_line_praise`, `first_line_hedging`, `first_line_length`,\n            `bridge`, `spam_never`, `spam_high`, `spam_medium`, `spam_subject` or `spam_structure`.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`pass`, `fail` or `skipped`.",
            "nullable": true
          },
          "severity": {
            "type": "string",
            "description": "`reject` or `flag`; present only on a failed rule.",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "matches": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The text that matched the rule (at most 20). `spam_medium` lists its words even when it passes.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailFindModel": {
        "required": [
          "status"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "personId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "pausedReason": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "verification": {
            "$ref": "#/components/schemas/EmailFindVerificationModel"
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "costCredits": {
            "type": "integer",
            "format": "int32"
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailFindVerificationModel": {
        "required": [
          "status"
        ],
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "verifiedBy": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceContentWarningDTO": {
        "type": "object",
        "properties": {
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "code": {
            "type": "string",
            "nullable": true
          },
          "severity": {
            "type": "string",
            "nullable": true
          },
          "path": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "policyVersion": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailSequenceStepModel"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "contentWarnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailSequenceContentWarningDTO"
            },
            "description": "Content-policy findings from this save (DEV-1323). Only on replace responses that\nhave findings; omitted otherwise.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 2210,
          "campaignId": 4821,
          "segmentId": 1207,
          "name": "Engineering leaders",
          "isActive": true,
          "steps": [
            {
              "id": 8841,
              "stepOrder": 1,
              "variant": "a",
              "subject": "Onboarding new engineers at {{company}}",
              "body": "Hi {{first_name}},\n\nMost engineering teams lose a new hire's first two weeks to setup and access requests. We help teams like yours get that down to two days.\n\nWorth a 15-minute look next week?\n\n{{sender_first_name}}",
              "bodyFormat": "plain",
              "waitDays": 0,
              "isActive": true,
              "openTrackingEnabled": false,
              "handwrittenEnabled": false
            },
            {
              "id": 8842,
              "stepOrder": 2,
              "variant": "a",
              "subject": "",
              "body": "Hi {{first_name}}, following up on this. Happy to send a 2-minute video instead if that is easier.\n\n{{sender_first_name}}",
              "bodyFormat": "plain",
              "waitDays": 3,
              "isActive": true,
              "openTrackingEnabled": false,
              "handwrittenEnabled": false
            }
          ],
          "createdAt": "2026-09-23T15:02:11Z",
          "modifiedAt": "2026-10-14T09:41:27Z"
        }
      },
      "EmailSequencePreviewContactModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequencePreviewModel": {
        "type": "object",
        "properties": {
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailSequencePreviewStepModel"
            },
            "nullable": true
          },
          "contact": {
            "$ref": "#/components/schemas/EmailSequencePreviewContactModel"
          },
          "sender": {
            "$ref": "#/components/schemas/EmailSequencePreviewSenderModel"
          },
          "senders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailSequencePreviewSenderModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequencePreviewSenderModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int32"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "warmupReputation": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "healthScore": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequencePreviewStepModel": {
        "type": "object",
        "properties": {
          "stepNumber": {
            "type": "integer",
            "format": "int32"
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "waitDays": {
            "type": "integer",
            "format": "int32"
          },
          "variables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailSequencePreviewVariableModel"
            },
            "nullable": true
          },
          "language": {
            "type": "string",
            "description": "DEV-1922: the locale of the approved localization the contact gets (fr-FR); omitted for the source text.",
            "nullable": true
          },
          "mirrorSubject": {
            "type": "string",
            "description": "The English mirror of the subject, filled like the subject; omitted with `language`.",
            "nullable": true
          },
          "mirrorBody": {
            "type": "string",
            "description": "The English mirror of the body, filled like the body; omitted with `language`.",
            "nullable": true
          },
          "qaScore": {
            "type": "integer",
            "description": "The judge's score of the localization, 0 to 100; omitted with `language`.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequencePreviewVariableModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "placeholder": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceSnapshotModel": {
        "type": "object",
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "format": "int32"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EmailSequenceSnapshotStepModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceSnapshotStepModel": {
        "type": "object",
        "properties": {
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "bodyFormat": {
            "type": "string",
            "nullable": true
          },
          "waitDays": {
            "type": "integer",
            "format": "int32"
          },
          "isActive": {
            "type": "boolean"
          },
          "handwrittenEnabled": {
            "type": "boolean"
          },
          "handwrittenBackground": {
            "type": "string",
            "nullable": true
          },
          "handwrittenIntro": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceStepModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "bodyFormat": {
            "type": "string",
            "nullable": true
          },
          "waitDays": {
            "type": "integer",
            "format": "int32"
          },
          "isActive": {
            "type": "boolean"
          },
          "openTrackingEnabled": {
            "type": "boolean"
          },
          "handwrittenEnabled": {
            "type": "boolean"
          },
          "handwrittenBackground": {
            "type": "string",
            "nullable": true
          },
          "handwrittenIntro": {
            "type": "string",
            "nullable": true
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-3558: set on an html step only. Reads carry `html_on_mailbox_inbox`, `html_size_near_cap` and\n`html_external_image:<host>` (DEV-3642); a save response adds `html_removed:<what>`, and\n`studio_pin_removed` (DEV-3559, any format) on a step whose pin the save dropped. Never blocks the save, never stored.",
            "nullable": true
          },
          "studioTemplateVersionId": {
            "type": "integer",
            "description": "DEV-3559: the Studio email version this step sends, rendered per lead; null when the step is not pinned.",
            "format": "int64",
            "nullable": true
          },
          "studioPin": {
            "$ref": "#/components/schemas/StudioPinModel"
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceTestSendModel": {
        "type": "object",
        "properties": {
          "stepsSent": {
            "type": "integer",
            "format": "int32"
          },
          "emailsAttempted": {
            "type": "integer",
            "format": "int32"
          },
          "emailsSent": {
            "type": "integer",
            "format": "int32"
          },
          "sentTo": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "failures": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "notes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-2729: sends that went out differently from the step as written, e.g. a handwritten letter sent as text.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceVersionDetailModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByEmail": {
            "type": "string",
            "nullable": true
          },
          "isRevert": {
            "type": "boolean"
          },
          "revertedFromVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "revertedFromVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "revertedFromCreatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "snapshot": {
            "$ref": "#/components/schemas/EmailSequenceSnapshotModel"
          }
        },
        "additionalProperties": false
      },
      "EmailSequenceVersionSaveModel": {
        "type": "object",
        "properties": {
          "sequence": {
            "$ref": "#/components/schemas/EmailSequenceModel"
          },
          "version": {
            "$ref": "#/components/schemas/SequenceVersionModel"
          },
          "versionWarning": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EmailValidityEnum": {
        "enum": [
          "unknown",
          "invalid",
          "risky",
          "verified",
          "safe",
          "catch_all",
          "verification_error"
        ],
        "type": "string"
      },
      "EngagementModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "dimension": {
            "type": "string",
            "nullable": true
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EngagementRowModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EngagementRowModel": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "humanCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "botCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "uniqueContactCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EstimateImageVariableRequest": {
        "type": "object",
        "properties": {
          "prompt": {
            "type": "string",
            "nullable": true
          },
          "references": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "string",
            "nullable": true
          },
          "quality": {
            "type": "string",
            "nullable": true
          },
          "spellingCheck": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "JSON body of `POST .../{variableKey}/estimate`: the draft fields to price, all optional (absent = saved value)."
      },
      "EventCountModel": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "EventCountsModel": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "to": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "counts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventCountModel"
            },
            "nullable": true
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EventDeliveryStatusModel": {
        "type": "object",
        "properties": {
          "active": {
            "type": "boolean",
            "description": "Kenso is delivering to the subscription."
          },
          "lastDeliveryAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastError": {
            "type": "string",
            "description": "`connection_refused`, `timeout`, `tls_error`, `http_4xx`, `http_5xx` or `challenge_failed`.",
            "nullable": true
          },
          "failedSince": {
            "type": "string",
            "description": "Deliveries have failed since this time; omitted while they succeed.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "SEP-3415 `deliveryStatus`. `lastError` is a category, never the endpoint's own text."
      },
      "EventModel": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "contactId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EventOccurrenceModel": {
        "type": "object",
        "properties": {
          "eventId": {
            "type": "string",
            "description": "The upstream event id; deduplicate on it within one subscription or poller.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "description": "The event type.",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "description": "When the event happened.",
            "format": "date-time"
          },
          "data": {
            "description": "Thin data: ids, the status or classification, and `links`. Fetch details with the API."
          },
          "cursor": {
            "type": "string",
            "description": "The position after this event.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A SEP-3415 `EventOccurrence`."
      },
      "EventOccurrencesModel": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/EventOccurrenceModel"
            },
            "nullable": true
          },
          "cursor": {
            "type": "string",
            "description": "Pass it back unchanged on the next poll. Opaque.",
            "nullable": true
          },
          "hasMore": {
            "type": "boolean",
            "description": "More events are waiting: poll again at once."
          },
          "truncated": {
            "type": "boolean",
            "description": "Events were skipped (older than `maxAgeMs`, or no longer kept): there is a gap before these."
          },
          "nextPollMs": {
            "type": "integer",
            "description": "Milliseconds to wait before the next poll.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A poll of the MCP event log (DEV-4030, SEP-3415 `events/poll`)."
      },
      "EventSubscriptionDeliveryRequest": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "description": "`webhook`, the only mode that takes a subscription.",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "The https callback URL.",
            "nullable": true
          },
          "secret": {
            "type": "string",
            "description": "The signing secret: `whsec_` + base64 of 24 to 64 random bytes. Never returned.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "EventSubscriptionGrantModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The subscription id, sent as `X-MCP-Subscription-Id` on every delivery.",
            "nullable": true
          },
          "refreshBefore": {
            "type": "string",
            "description": "Subscribe again with the same key before this time, or the subscription expires.",
            "format": "date-time"
          },
          "cursor": {
            "type": "string",
            "description": "The safe-to-persist watermark: every event at or before it was delivered or given up on.",
            "nullable": true
          },
          "truncated": {
            "type": "boolean",
            "description": "Delivery starts later than the cursor you supplied: events were skipped."
          },
          "deliveryStatus": {
            "$ref": "#/components/schemas/EventDeliveryStatusModel"
          }
        },
        "additionalProperties": false,
        "description": "The grant of a subscribe or renewal (SEP-3415 `events/subscribe`)."
      },
      "EventSubscriptionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "description": "The event type.",
            "nullable": true
          },
          "arguments": {
            "description": "The filters it was made with (`campaignId`, `classification`)."
          },
          "url": {
            "type": "string",
            "description": "Where it delivers.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`active`, `expired` or `terminated`.",
            "nullable": true
          },
          "refreshBefore": {
            "type": "string",
            "format": "date-time"
          },
          "verifiedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "deliveryStatus": {
            "$ref": "#/components/schemas/EventDeliveryStatusModel"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "One of your webhook event subscriptions. The signing secret is never returned."
      },
      "EventSubscriptionUnsubscribeDelivery": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExternalBookingInviteeModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ExternalBookingModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "hostMemberId": {
            "type": "integer",
            "format": "int64"
          },
          "startAt": {
            "type": "string",
            "format": "date-time"
          },
          "endAt": {
            "type": "string",
            "format": "date-time"
          },
          "invitee": {
            "$ref": "#/components/schemas/ExternalBookingInviteeModel"
          },
          "contactId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "personId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "accountId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "attribution": {
            "type": "string",
            "nullable": true
          },
          "meetingId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "cancelledAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "cancelReason": {
            "type": "string",
            "nullable": true
          },
          "noShowAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "FilterCondition": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "nullable": true
          },
          "operator": {
            "$ref": "#/components/schemas/ComparisonOperatorEnum"
          },
          "value": {
            "nullable": true
          },
          "dataType": {
            "$ref": "#/components/schemas/DataTypeEnum"
          }
        },
        "additionalProperties": false
      },
      "FilterGroup": {
        "type": "object",
        "properties": {
          "operator": {
            "$ref": "#/components/schemas/LogicalOperatorEnum"
          },
          "conditions": {
            "$ref": "#/components/schemas/FilterCondition"
          },
          "children": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterGroup"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "FilterOptionItem": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "category": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "FloatRange": {
        "type": "object",
        "properties": {
          "min": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "max": {
            "type": "number",
            "format": "float",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ForwardThreadRequest": {
        "type": "object",
        "properties": {
          "body": {
            "type": "string",
            "nullable": true
          },
          "senderEmailId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "contentType": {
            "type": "string",
            "nullable": true
          },
          "replyAll": {
            "type": "boolean"
          },
          "injectPreviousEmailBody": {
            "type": "boolean",
            "nullable": true
          },
          "replyTemplateId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "useDedicatedIps": {
            "type": "boolean"
          },
          "to": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadAddressRequest"
            },
            "nullable": true
          },
          "cc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadAddressRequest"
            },
            "nullable": true
          },
          "bcc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadAddressRequest"
            },
            "nullable": true
          },
          "delaySeconds": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "archiveAfterSend": {
            "type": "boolean"
          },
          "attachmentIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "FreeWorkItemEnum": {
        "enum": [
          "ken_db_email",
          "email_verification",
          "enrichment_person",
          "ken_search_person",
          "website_page",
          "launch_offer",
          "enrichment_company",
          "enrichment_tech_stack"
        ],
        "type": "string"
      },
      "FundingRoundsExportAllowanceModel": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Rows the workspace may export this month.",
            "format": "int32"
          },
          "used": {
            "type": "integer",
            "description": "Rows exported this month, including exports still running.",
            "format": "int32"
          },
          "remaining": {
            "type": "integer",
            "description": "Rows left this month. 2147483647 when Ken.Scraper.API.Canonical.FundingRoundsExportAllowanceModel.IsUnlimited.",
            "format": "int32"
          },
          "maxPerExport": {
            "type": "integer",
            "description": "Most rows one export can return.",
            "format": "int32"
          },
          "isUnlimited": {
            "type": "boolean",
            "description": "True when the workspace's billing bypasses limits."
          },
          "periodStart": {
            "type": "string",
            "description": "First instant of this calendar month, UTC.",
            "format": "date-time"
          },
          "periodEnd": {
            "type": "string",
            "description": "First instant of next calendar month, UTC. The allowance resets then.",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "The workspace's funding export allowance for the current calendar month (UTC)."
      },
      "GenerateLocalizationsRequest": {
        "type": "object",
        "properties": {
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Locales the campaign enables, such as `fr-FR`.",
            "nullable": true
          },
          "stepIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Email or LinkedIn step ids of the campaign. An email and a LinkedIn step can share an id: add `channel` to pick one.",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "description": "`email` or `linkedin`: only that channel's steps. Absent means both.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of POST /v1/campaigns/{campaignId}/localizations. Each list is optional: absent or empty means all."
      },
      "GradeEmailCopyRequest": {
        "type": "object",
        "properties": {
          "copy": {
            "type": "string",
            "nullable": true
          },
          "subjectKey": {
            "type": "string",
            "nullable": true
          },
          "refresh": {
            "type": "boolean"
          },
          "channel": {
            "type": "string",
            "description": "The sequence step the copy is for: `email` (the default when omitted),\n`linkedin_connection` or `linkedin_message`.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "The campaign the copy is for. A recruiting campaign grades with the recruiting rubric and keeps its own saved\ngrade. Omit it (or send 0) to grade as before. A campaign of another workspace answers 404.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ImageVariableCountsModel": {
        "type": "object",
        "properties": {
          "ready": {
            "type": "integer",
            "format": "int32"
          },
          "pending": {
            "type": "integer",
            "format": "int32"
          },
          "failed": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Lead images of a per_prospect variable: current ready and failed images, and every pending one."
      },
      "ImageVariableEstimateModel": {
        "type": "object",
        "properties": {
          "leadsNow": {
            "type": "integer",
            "description": "Leads that would get an image now, including the leads whose image would be replaced.",
            "format": "int32"
          },
          "replaceCount": {
            "type": "integer",
            "description": "Of those, leads whose current ready image would be replaced by the change.",
            "format": "int32"
          },
          "creditsPerImage": {
            "type": "number",
            "format": "double"
          },
          "creditsNow": {
            "type": "number",
            "format": "double"
          },
          "creditsPerNewLead": {
            "type": "number",
            "description": "Credits per lead that becomes eligible later; 0 for a shared variable.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "What running the variable as drafted would generate now and cost. Every credit field is credits, not millicredits."
      },
      "ImageVariableListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageVariableModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          },
          "linkHostReady": {
            "type": "boolean"
          },
          "coverage": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "description": "`leads` plus each reference wire name (`profile_photo`, ...), as counts of leads.",
            "nullable": true
          },
          "models": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageVariableModelOption"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The list envelope of `GET /v1/campaigns/{campaignId}/image-variables`: the variables by key, plus whether the\nworkspace has a link host to send images from, how many leads have each reference, and the models with prices."
      },
      "ImageVariableModel": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "The token key, normalized like custom and AI variables (`hero_image` for `{{hero_image}}`).",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "`shared` or `per_prospect`.",
            "nullable": true
          },
          "prompt": {
            "type": "string",
            "description": "The image prompt; per_prospect prompts use lead tokens such as `{{first_name}}`.",
            "nullable": true
          },
          "references": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Reference pictures: `profile_photo`, `company_logo`, `sender_logo`, `website_screenshot`, `custom_image`.",
            "nullable": true
          },
          "model": {
            "type": "string",
            "description": "Image model id from the list's `models`.",
            "nullable": true
          },
          "size": {
            "type": "string",
            "description": "`1024x1024`, `1536x1024` or `1024x1536`.",
            "nullable": true
          },
          "quality": {
            "type": "string",
            "description": "`low`, `medium` or `high`.",
            "nullable": true
          },
          "spellingCheck": {
            "type": "boolean",
            "description": "Checks the text in each image against the prompt and regenerates once on a mismatch."
          },
          "requiredForSending": {
            "type": "boolean",
            "description": "A lead without a ready image is held from steps that use the token."
          },
          "enabled": {
            "type": "boolean",
            "description": "per_prospect: every eligible lead gets an image, charged per ready image. Off keeps the existing images."
          },
          "altText": {
            "type": "string",
            "nullable": true
          },
          "sharedImage": {
            "$ref": "#/components/schemas/SharedImageModel"
          },
          "counts": {
            "$ref": "#/components/schemas/ImageVariableCountsModel"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "The canonical ImageVariable (DEV-6700 task 11): a campaign's image token `{{key}}` and how it is made. Kind is\n`shared` (one image for every lead) or `per_prospect` (one image per lead, generated while\nKen.Scraper.API.Canonical.ImageVariableModel.Enabled)."
      },
      "ImageVariableModelOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "creditsPerImage": {
            "type": "number",
            "description": "Credits (not millicredits) per per_prospect image on this workspace's route.",
            "format": "double"
          }
        },
        "additionalProperties": false,
        "description": "An image model the variable can use, with its estimated credits per image."
      },
      "ImageVariableTestModel": {
        "type": "object",
        "properties": {
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CampaignImageModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The images a test on up to 5 leads made."
      },
      "InboundWebhookDeliveryModel": {
        "type": "object",
        "properties": {
          "receivedAt": {
            "type": "string",
            "format": "date-time"
          },
          "outcome": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "httpStatus": {
            "type": "integer",
            "format": "int32"
          },
          "body": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InboundWebhookMappingTestModel": {
        "type": "object",
        "properties": {
          "resolvedFields": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "resolvedCustomVariables": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "unresolvedPaths": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "wouldBeAccepted": {
            "type": "boolean"
          },
          "rejectionReason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InboundWebhookModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "description": "`campaign` (each delivery uploads a lead to its campaign), `people` (each delivery creates or updates a person)\n            or `website` (the site's rb2b, Vector, Snitcher or Warmly webhook: each delivery records a website visit; set up through\n            `PATCH /v1/website`).",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "The campaign a `campaign` webhook feeds; omitted for the other kinds.",
            "format": "int64",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "samplePayloadJson": {
            "type": "string",
            "nullable": true
          },
          "mapping": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookAssignment"
            },
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "lastReceivedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "acceptedCount": {
            "type": "integer",
            "format": "int64"
          },
          "rejectedCount": {
            "type": "integer",
            "format": "int64"
          },
          "preset": {
            "type": "string",
            "description": "A `people` webhook's form preset, when it was created from one, or a `website` webhook's provider.",
            "nullable": true
          },
          "app": {
            "type": "string",
            "description": "A `people` webhook's sending app: `zapier`, `make` or `n8n`. Omitted when none.",
            "nullable": true
          },
          "defaultOwnerMemberId": {
            "type": "integer",
            "description": "The member who owns the people a `people` webhook creates. Omitted: the workspace's intake settings decide.",
            "format": "int64",
            "nullable": true
          },
          "createAccounts": {
            "type": "boolean",
            "description": "A `people` webhook's account choice: `false` never creates the person's account; omitted, the workspace's intake settings decide.",
            "nullable": true
          },
          "peopleCreated": {
            "type": "integer",
            "description": "People a `people` webhook created. Omitted for a `campaign` webhook.",
            "format": "int64",
            "nullable": true
          },
          "peopleUpdated": {
            "type": "integer",
            "description": "People a `people` webhook matched and updated. Omitted for a `campaign` webhook.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InboxBulkFailure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InboxBulkResult": {
        "type": "object",
        "properties": {
          "updatedCount": {
            "type": "integer",
            "description": "Inboxes updated. With `profileImageUrl`, the inboxes whose photo InboxKit accepted; the rest are in\nKen.Scraper.API.Canonical.InboxBulkResult.Failed.",
            "format": "int32"
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboxBulkFailure"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InboxConnectSessionModel": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "description": "`google` or `microsoft`.",
            "nullable": true
          },
          "purpose": {
            "type": "string",
            "description": "`primary` (a member's own mailbox), `campaign` (a shared campaign mailbox), or `calendar` (a member's\n            calendar alone, from `POST /v1/calendar-accounts/connect-sessions`, DEV-4022).",
            "nullable": true
          },
          "appName": {
            "type": "string",
            "description": "The OAuth app the user grants: \"Kenso Workspace\" for primary and calendar, \"Kenso Mail\" for campaign.",
            "nullable": true
          },
          "clientId": {
            "type": "string",
            "description": "The OAuth app's public client id, for an admin who has to trust the app first.",
            "nullable": true
          },
          "authorizationUrl": {
            "type": "string",
            "nullable": true
          },
          "adminUrl": {
            "type": "string",
            "description": "Where an admin trusts the app: Google Admin console, or the Microsoft admin-consent URL.",
            "nullable": true
          },
          "adminConsentUrl": {
            "type": "string",
            "description": "Microsoft only: the Entra admin-consent URL for this app.",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "A Gmail or Microsoft connect session (DEV-1652). Nothing is stored: open Ken.Scraper.API.Canonical.InboxConnectSessionModel.AuthorizationUrl\nbefore Ken.Scraper.API.Canonical.InboxConnectSessionModel.ExpiresAt, or create a fresh session."
      },
      "InboxConnectionModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`connected`, `disconnected`, `auth_expired` or `error`.",
            "nullable": true
          },
          "checkedAt": {
            "type": "string",
            "description": "When Kenso last verified the connection against the provider.",
            "format": "date-time",
            "nullable": true
          },
          "error": {
            "type": "string",
            "description": "The provider's short reason when the status is `auth_expired` or `error`. Never secret.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Health of Kenso's own connection to a mailbox, served on `inbox.connection` (DEV-3972)."
      },
      "InboxHealthBlockModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "`paused` (a member paused the inbox), `send_blocked` (Ken blocked it, for example after a failed\n            placement test) or `sending_paused` (a pause over the inbox, its domain or the workspace).",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Why, as recorded: usually a machine code such as `mailbox_hard_bounce_rate`. Omitted when none was recorded.",
            "nullable": true
          },
          "until": {
            "type": "string",
            "description": "When the block ends, UTC. Omitted for `paused`, which lasts until a member resumes the inbox.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InboxHealthModel": {
        "type": "object",
        "properties": {
          "sentToday": {
            "type": "integer",
            "description": "Sends the provider accepted in the inbox's send day so far, campaign and 1:1 alike.",
            "format": "int32"
          },
          "reservedToday": {
            "type": "integer",
            "description": "Slots held by sends in flight.",
            "format": "int32"
          },
          "limit": {
            "type": "integer",
            "description": "Today's effective cap: the inbox's daily limit after its ramp, its domain's ramp and the provider maximum.",
            "format": "int32"
          },
          "remaining": {
            "type": "integer",
            "description": "Ken.Scraper.API.Canonical.InboxHealthModel.Limit less Ken.Scraper.API.Canonical.InboxHealthModel.SentToday and Ken.Scraper.API.Canonical.InboxHealthModel.ReservedToday, never below 0.",
            "format": "int32"
          },
          "dayEndsAt": {
            "type": "string",
            "description": "When the send day resets, UTC: the day in the zone of the inbox's campaigns, New York when none names one.",
            "format": "date-time"
          },
          "rampDay": {
            "type": "integer",
            "description": "The ramp's day, 1 during the first 24-hour sending window, and still present once the ramp completes. Omitted\nwhen the cap could not be resolved from send history (the cap kill switch, or a failed history read), so the\nramp was not read.",
            "format": "int32",
            "nullable": true
          },
          "rampComplete": {
            "type": "boolean",
            "description": "The ramp reached its target and no longer lowers the cap. False when Ken.Scraper.API.Canonical.InboxHealthModel.RampDay is omitted."
          },
          "warmupReadiness": {
            "type": "string",
            "description": "The warmup gate's verdict, in the values `GET /v1/inboxes/{inboxId}/warmup` serves as\n`readiness.outcome`: `ready`, `too_young`, `unconfirmed`, `bypassed`,\n`provider_stale`, or `unavailable` (no fresh provider evidence, or no verdict for the inbox).",
            "nullable": true
          },
          "blocks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboxHealthBlockModel"
            },
            "description": "What holds the inbox back now. Empty when nothing does.",
            "nullable": true
          },
          "bounceRate7d": {
            "type": "number",
            "description": "Hard bounces over accepted sends in the last 7 days, 0 to 1. Omitted with no accepted sends in that window, and\nwhen Ken.Scraper.API.Canonical.InboxHealthModel.RampDay is omitted.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "`health` on `GET /v1/inboxes/{inboxId}` (DEV-3672). Mapped by M:Ken.Scraper.API.Canonical.InboxMapper.ApplyHealth(Ken.Scraper.API.Canonical.InboxModel,Ken.Scraping.Application.Queries.EmailOrchestrator.InboxHealthDto)."
      },
      "InboxImportJobModel": {
        "type": "object",
        "properties": {
          "connectedCount": {
            "type": "integer",
            "format": "int32"
          },
          "failedCount": {
            "type": "integer",
            "format": "int32"
          },
          "skippedCount": {
            "type": "integer",
            "format": "int32"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "rows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InboxImportRowModel"
            },
            "description": "Processed rows ordered by `index`, empty until the first row has a result. Returned by create and get;\nomitted from lists and for a caller without Delivery view.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Counts and per-row results of an `inbox_import` job. Passwords are never returned."
      },
      "InboxImportRowModel": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "description": "Zero-based position of the row in the request's `rows` array.",
            "format": "int32"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`connected`, `failed`, or `skipped`.",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "description": "The connected inbox, the existing inbox a skipped row matched, or the disconnected inbox a failed\nconnect left in the workspace. Omitted when there is none.",
            "format": "int64",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "description": "Omitted for a connected row. On a skipped row, `already_exists`, `duplicate_in_file`, or the reason the\nimport stopped before the row's turn: `feature_disabled` (the `inbox_csv_import` flag went off) or\n`forbidden` (the caller lost Delivery edit). On a failed row, `email_in_use` (another inbox in Kenso holds\nthe email), `host_failure_limit` (not tried: its host refused several logins or could not be reached earlier\nin the import) or a canonical error code (`validation_failed`, `forbidden`, `service_unavailable`,\n`internal_error`, ...).",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One processed row of an inbox import."
      },
      "InboxModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "signature": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "description": "`sending` (a campaign inbox), `replies` (DEV-3320): the workspace's shared replies@ inbox, the\n            address campaign replies go to, or `retired` (DEV-3194): a campaign inbox staff retired to receive-only.\n            A `replies` or `retired` inbox only receives: it never joins a campaign pool or warmup, and Kenso keeps\n            reading its mail.",
            "nullable": true
          },
          "captureUntil": {
            "type": "string",
            "description": "When a `retired` inbox's reply capture window ends, UTC (DEV-3194). Nothing happens automatically then:\nKenso keeps reading the inbox until staff delete it. Omitted unless the inbox is retired, and on\n`availableForCampaignId` lists.",
            "format": "date-time",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "dailySendLimit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "forwarding": {
            "type": "string",
            "nullable": true
          },
          "forwardingDestination": {
            "type": "string",
            "nullable": true
          },
          "profileImageUrl": {
            "type": "string",
            "description": "The mailbox photo to show (DEV-4061): the photo Kenso set on the mailbox, else the photo InboxKit reports for it.\nLinkedIn CDN URLs are dropped. Omitted when there is none, and on `availableForCampaignId` lists.",
            "nullable": true
          },
          "profilePhotoSupport": {
            "type": "string",
            "description": "Whether Kenso can set this mailbox's sender photo (DEV-4061): `google` (a Kenso-managed Google mailbox),\n`microsoft` (a Kenso-managed Microsoft or Azure mailbox), `google_account` or `microsoft_account`\n(a member's own mailbox connected through Kenso sign-in, whose photo only its owner can change) or `none`.\nSetting a photo also needs the workspace's `inbox_photos` flag. Omitted on `availableForCampaignId`\nlists.",
            "nullable": true
          },
          "profilePhotoStatus": {
            "type": "string",
            "description": "Whether the photo Kenso set on the mailbox landed (DEV-4123): `pending` (InboxKit queued it for a Microsoft or\nAzure mailbox and has not applied it yet), `applied` or `failed` (InboxKit did not apply it: no photo\nshows, and Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoError says why). Omitted for photos set before this tracking, when Kenso set\nnone, and on `availableForCampaignId` lists.",
            "nullable": true
          },
          "profilePhotoStatusAt": {
            "type": "string",
            "description": "When Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus was last set, UTC: for `pending`, when InboxKit took the photo.",
            "format": "date-time",
            "nullable": true
          },
          "profilePhotoError": {
            "type": "string",
            "description": "Why the photo failed, only with Ken.Scraper.API.Canonical.InboxModel.ProfilePhotoStatus`failed`.",
            "nullable": true
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "pausedAt": {
            "type": "string",
            "description": "When a member paused outreach from this inbox (DEV-2315), UTC. Null when it is not paused. A paused\ninbox holds campaign steps, triggers and approved Accounts 1:1 email; warmup and reply sync keep running.\nIndependent of Ken.Scraper.API.Canonical.InboxModel.Status.",
            "format": "date-time",
            "nullable": true
          },
          "isKenSendable": {
            "type": "boolean",
            "nullable": true
          },
          "sendingProvider": {
            "type": "string",
            "description": "DEV-3555: the sending provider slug (`resend`, `agentmail`, ...) when the inbox is an identity on a\nsending provider connection, which sends through that provider's API. Omitted for every other inbox.",
            "nullable": true
          },
          "isIngestReady": {
            "type": "boolean",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "description": "The workspace member whose own mailbox this is (DEV-1652). Omitted for a shared campaign inbox.\nAn owned inbox never joins a campaign pool or warmup.",
            "format": "int64",
            "nullable": true
          },
          "isPrimary": {
            "type": "boolean",
            "description": "True when the inbox is owned by a member and its address sits on one of the workspace's domains: its email\ndomain or any domain listed under Settings > Company (DEV-3886). Derived on read, so it follows a later\nchange to that list. Only a primary inbox sends the member's 1:1 email."
          },
          "connectionApp": {
            "type": "string",
            "description": "Which Kenso OAuth app the Google or Microsoft connection was granted to: `ken_mail` (campaign\nmailboxes) or `ken_workspace` (a member's own mailbox). Omitted for SMTP and unconnected inboxes.",
            "nullable": true
          },
          "trackOpens": {
            "type": "boolean",
            "description": "The owner's Track opens option (DEV-1652). Off by default. When on, replies the member sends from this\nmailbox in the Inbox carry one open pixel; their 1:1 Accounts email never does (DEV-3062). Present only\non a member's own mailbox (Ken.Scraper.API.Canonical.InboxModel.OwnerMemberId set); omitted for a shared campaign inbox.",
            "nullable": true
          },
          "usedBy": {
            "$ref": "#/components/schemas/UsedByModel"
          },
          "warmup": {
            "$ref": "#/components/schemas/InboxWarmupSummaryModel"
          },
          "sendBlock": {
            "$ref": "#/components/schemas/InboxSendBlockModel"
          },
          "healthScore": {
            "type": "integer",
            "description": "The Kenso Health Score, 0-100, from the latest InboxKit health snapshot (DEV-1611). Omitted when InboxKit\nhas reported no health for the inbox, and on `availableForCampaignId` lists.",
            "format": "int32",
            "nullable": true
          },
          "tenantHost": {
            "type": "string",
            "description": "The Microsoft 365 tenant of a Microsoft or Azure inbox, `<tenant>.onmicrosoft.com`, read hourly from\nits domain's public DKIM record (DEV-2309). Inboxes that share it share one tenant, the unit a Microsoft tenant\nban hits. Staff only (`super_admin`): omitted for every other caller, and omitted until it is resolved.",
            "nullable": true
          },
          "lastSentAt": {
            "type": "string",
            "description": "The inbox's last send the provider accepted, UTC (DEV-3972). Warmup sends do not count. Omitted when it\nsent nothing in the last 30 days, or when that read failed.",
            "format": "date-time",
            "nullable": true
          },
          "connection": {
            "$ref": "#/components/schemas/InboxConnectionModel"
          },
          "health": {
            "$ref": "#/components/schemas/InboxHealthModel"
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 5530,
          "email": "alex@mail.example.com",
          "firstName": "Alex",
          "lastName": "Rivera",
          "displayName": "Alex Rivera",
          "signature": "Alex Rivera\nNorthwind Outbound",
          "status": "active",
          "role": "sending",
          "provider": "google",
          "domainId": 640,
          "dailySendLimit": 30,
          "profilePhotoSupport": "google",
          "tagIds": [ ],
          "createdAt": "2026-08-31T10:15:00Z",
          "updatedAt": "2026-10-14T09:41:27Z",
          "isPrimary": false,
          "usedBy": {
            "campaigns": [
              {
                "id": 4821,
                "name": "Q4 SaaS founders",
                "status": "active"
              }
            ],
            "accounts": false
          },
          "warmup": {
            "daysLeft": 0
          },
          "healthScore": 94,
          "lastSentAt": "2026-10-14T09:12:40Z"
        }
      },
      "InboxRenameModel": {
        "type": "object",
        "properties": {
          "inbox": {
            "$ref": "#/components/schemas/InboxModel"
          },
          "reconnected": {
            "type": "boolean",
            "description": "True when Kenso reconnected the inbox's sending connection under the new address."
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Follow-up steps that did not finish (the reconnect, for example). The rename itself succeeded.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-15: the result of `POST /v1/inboxes/{inboxId}/rename`."
      },
      "InboxSendBlockModel": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "Reason code of an automated block (for example `mailbox_hard_bounce_rate`). Omitted for a\nmanual or rename block.",
            "nullable": true
          },
          "until": {
            "type": "string",
            "description": "When the block ends (UTC). The inbox sends no campaign mail until then.",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "InboxWarmupEnrollmentFailureModel": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "description": "The warmup provider the enrollment targeted. Today always `instantly`.",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "Failure class: imap_credentials, missing_password, provider_5xx, provider_rejected,\ntransport, credential_lookup_failed, outlook_disabled, capacity, status_unconfirmed,\nor an account-health reason.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "The provider's warmup status for this mailbox (for example `enroll_failed`).",
            "nullable": true
          },
          "failureCount": {
            "type": "integer",
            "description": "Consecutive failed enrollment attempts.",
            "format": "int32"
          },
          "retryAt": {
            "type": "string",
            "description": "Earliest next automatic enrollment attempt. Null when retries stopped: the mailbox\nstays unenrolled until its credential changes.",
            "format": "date-time",
            "nullable": true
          },
          "isStopped": {
            "type": "boolean",
            "description": "True when automatic retries stopped (no Ken.Scraper.API.Canonical.InboxWarmupEnrollmentFailureModel.RetryAt)."
          }
        },
        "additionalProperties": false
      },
      "InboxWarmupModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "not_started, pending, in_progress, paused, completed, maintenance, failed, or degraded.\nDerived from the live warmup provider's status when one tracks the inbox, otherwise from\nthe legacy inbox warmup column (DEV-1456). An Azure inbox with no warmup subscription\n(cancelled or never bought) is failed: Kenso cannot enroll Azure (DEV-3313).\nVendor-neutral: no provider name on the wire.",
            "nullable": true
          },
          "enabled": {
            "type": "boolean",
            "description": "Warmup is switched on: the provider is warming the inbox or activating its warmup."
          },
          "startedAt": {
            "type": "string",
            "description": "When warmup started. Falls back to the first day a live warmup provider reported\nwarmup sends when the inbox row has no start time (DEV-1454).",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "readiness": {
            "$ref": "#/components/schemas/InboxWarmupReadinessModel"
          },
          "enrollmentFailure": {
            "$ref": "#/components/schemas/InboxWarmupEnrollmentFailureModel"
          }
        },
        "additionalProperties": false
      },
      "InboxWarmupReadinessModel": {
        "type": "object",
        "properties": {
          "outcome": {
            "type": "string",
            "description": "ready, bypassed, unconfirmed, too_young, provider_stale, or unavailable.",
            "nullable": true
          },
          "isReady": {
            "type": "boolean",
            "description": "Warmup is confirmed: the gate says ready, or an outreach bypass covers the inbox."
          },
          "isHeld": {
            "type": "boolean",
            "description": "The gate keeps cold sends off this inbox while enforcement is on."
          },
          "isEnforced": {
            "type": "boolean",
            "description": "Whether the gate enforces holds today. When false, a held inbox still sends."
          },
          "firstWarmupSendDate": {
            "type": "string",
            "description": "First day (YYYY-MM-DD, UTC) a live provider reported warmup sends.",
            "nullable": true
          },
          "lastWarmupSendDate": {
            "type": "string",
            "description": "Latest day (YYYY-MM-DD, UTC) a live provider reported warmup sends with warmup on.",
            "nullable": true
          },
          "daysInWarmup": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "minimumWarmupDays": {
            "type": "integer",
            "format": "int32"
          },
          "hasMinWeekOverride": {
            "type": "boolean"
          },
          "hasOutreachBypass": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "InboxWarmupSummaryModel": {
        "type": "object",
        "properties": {
          "daysLeft": {
            "type": "integer",
            "description": "Days until the inbox reaches the minimum warmup age the send gate requires, counted from the\nfirst provider-reported warmup send. 0 once reached, or when an outreach bypass or min-week\noverride waives it (an outreach bypass reports 0 even before any warmup send).",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InfraFindingModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "workspaceId": {
            "type": "integer",
            "description": "Absent on the staff-only findings that belong to no workspace (renewal_shortfall, registrar_orphan).",
            "format": "int64",
            "nullable": true
          },
          "workspaceName": {
            "type": "string",
            "description": "Staff lists only.",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "billing_leak, provider_cancelled, warmup_missing, idle_domain, domain_expiring, inbox_no_domain, disconnected_inbox, renewal_shortfall, registrar_orphan.",
            "nullable": true
          },
          "subjectType": {
            "type": "string",
            "description": "inbox, domain, provider_account, registrar_domain.",
            "nullable": true
          },
          "subjectId": {
            "type": "integer",
            "description": "The inbox or domain id; absent for a provider account or a registrar domain Kenso has no row for.",
            "format": "int64",
            "nullable": true
          },
          "subjectKey": {
            "type": "string",
            "description": "The finding's stable key, for example `inbox:123` or `registrar_domain:porkbun:example.com`.",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "description": "inboxkit, porkbun, ken.",
            "nullable": true
          },
          "severity": {
            "type": "string",
            "description": "critical, warning, info.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "open, snoozed, ignored, resolved.",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "evidence": {
            "description": "What the detector saw; its keys depend on the kind."
          },
          "suggestedAction": {
            "type": "string",
            "nullable": true
          },
          "monthlyCost": {
            "$ref": "#/components/schemas/MoneyModel"
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "resolvedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "snoozedUntil": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "An infra finding (DEV-6197): one problem with an inbox, a domain or a provider account. Read-only."
      },
      "InfraKindSummaryModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "openCount": {
            "type": "integer",
            "format": "int32"
          },
          "critical": {
            "type": "integer",
            "format": "int32"
          },
          "warning": {
            "type": "integer",
            "format": "int32"
          },
          "info": {
            "type": "integer",
            "format": "int32"
          },
          "monthlyCost": {
            "$ref": "#/components/schemas/MoneyModel"
          }
        },
        "additionalProperties": false
      },
      "InfraSeverityCountsModel": {
        "type": "object",
        "properties": {
          "critical": {
            "type": "integer",
            "format": "int32"
          },
          "warning": {
            "type": "integer",
            "format": "int32"
          },
          "info": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "InfraSummaryModel": {
        "type": "object",
        "properties": {
          "openCount": {
            "type": "integer",
            "format": "int32"
          },
          "snoozedCount": {
            "type": "integer",
            "format": "int32"
          },
          "bySeverity": {
            "$ref": "#/components/schemas/InfraSeverityCountsModel"
          },
          "byKind": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InfraKindSummaryModel"
            },
            "nullable": true
          },
          "monthlyCostAtStake": {
            "$ref": "#/components/schemas/MoneyModel"
          },
          "lastSweep": {
            "$ref": "#/components/schemas/InfraSweepModel"
          }
        },
        "additionalProperties": false
      },
      "InfraSweepDetectorModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "subjectType": {
            "type": "string",
            "nullable": true
          },
          "outcome": {
            "type": "string",
            "description": "completed, failed, skipped. Only a completed detector resolves findings.",
            "nullable": true
          },
          "found": {
            "type": "integer",
            "format": "int32"
          },
          "opened": {
            "type": "integer",
            "format": "int32"
          },
          "resolved": {
            "type": "integer",
            "format": "int32"
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "InfraSweepModel": {
        "type": "object",
        "properties": {
          "sweepId": {
            "type": "integer",
            "format": "int64"
          },
          "trigger": {
            "type": "string",
            "description": "schedule or staff. Absent when a start returned a sweep that was already running.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "running, completed, failed.",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "format": "date-time"
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "detectors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InfraSweepDetectorModel"
            },
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "IntRange": {
        "type": "object",
        "properties": {
          "min": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "max": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "IntakePersonBody": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          },
          "linkedinUrl": {
            "type": "string",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "sourceDetail": {
            "type": "string",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "leadStatus": {
            "type": "string",
            "nullable": true
          },
          "customFields": {
            "type": "object",
            "additionalProperties": { },
            "nullable": true
          },
          "createAccount": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "JobErrorModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "JobModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "progress": {
            "$ref": "#/components/schemas/JobProgressModel"
          },
          "resource": {
            "$ref": "#/components/schemas/JobResourceModel"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "downloadUrl": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "$ref": "#/components/schemas/JobErrorModel"
          },
          "result": {
            "description": "Upstream payload for a scraping job get. Omitted for other types and for lists.",
            "nullable": true
          },
          "domainsListed": {
            "type": "integer",
            "description": "Listed-domain count stored by a completed domain health sweep. Omitted until that count exists.",
            "format": "int32",
            "nullable": true
          },
          "excludedLibraryContacts": {
            "type": "integer",
            "description": "Contacts from a Kenso library list a contact export left out (they are never exported), including 0. Only on\ncontact_export jobs of kind contacts, campaign and advanced; omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "inboxImport": {
            "$ref": "#/components/schemas/InboxImportJobModel"
          },
          "personImport": {
            "$ref": "#/components/schemas/PersonImportJobModel"
          },
          "skipped": {
            "$ref": "#/components/schemas/ContactImportSkipsModel"
          }
        },
        "additionalProperties": false
      },
      "JobPostSearchImportResult": {
        "type": "object",
        "properties": {
          "jobId": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "JobPostingsExportAllowanceModel": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "description": "Rows the workspace may export this month: its lead limit.",
            "format": "int32"
          },
          "used": {
            "type": "integer",
            "description": "Rows exported this month, including exports still running.",
            "format": "int32"
          },
          "remaining": {
            "type": "integer",
            "description": "Rows left this month. 2147483647 when Ken.Scraper.API.Canonical.JobPostingsExportAllowanceModel.IsUnlimited.",
            "format": "int32"
          },
          "maxPerExport": {
            "type": "integer",
            "description": "Most rows one export can return.",
            "format": "int32"
          },
          "isUnlimited": {
            "type": "boolean",
            "description": "True when the workspace bypasses limits or its lead limit is unlimited."
          },
          "periodStart": {
            "type": "string",
            "description": "First instant of this calendar month, UTC.",
            "format": "date-time"
          },
          "periodEnd": {
            "type": "string",
            "description": "First instant of next calendar month, UTC. The allowance resets then.",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "The workspace's job-postings export allowance for the current calendar month (UTC)."
      },
      "JobProgressModel": {
        "type": "object",
        "properties": {
          "completed": {
            "type": "integer",
            "format": "int32"
          },
          "total": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "JobResourceModel": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "id": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "JsonNode": {
        "type": "object",
        "properties": {
          "options": {
            "$ref": "#/components/schemas/JsonNodeOptions"
          },
          "parent": {
            "$ref": "#/components/schemas/JsonNode"
          },
          "root": {
            "$ref": "#/components/schemas/JsonNode"
          }
        },
        "additionalProperties": false
      },
      "JsonNodeOptions": {
        "type": "object",
        "properties": {
          "propertyNameCaseInsensitive": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "LaunchForecastModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "progress": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "estimatedFinishAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "confidence": {
            "type": "string",
            "nullable": true
          },
          "reasonCodes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "statusExplanation": {
            "type": "string",
            "nullable": true
          },
          "remainingEmailCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "effectiveDailyCapacity": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "scheduledNext3DayCount": {
            "type": "integer",
            "format": "int32"
          },
          "effectiveScheduledNext3DayCount": {
            "type": "integer",
            "format": "int32"
          },
          "projectedNext3DayCount": {
            "type": "integer",
            "format": "int32"
          },
          "effectiveProjectedNext3DayCount": {
            "type": "integer",
            "format": "int32"
          },
          "readyContactCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "assignedTodayCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "acceptedTodayCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "calculatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "isStale": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "LaunchReadinessModel": {
        "type": "object",
        "properties": {
          "canLaunch": {
            "type": "boolean"
          },
          "reasons": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaunchReadinessReasonModel"
            },
            "nullable": true
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LaunchReadinessReasonModel"
            },
            "description": "Does not affect Ken.Scraper.API.Canonical.LaunchReadinessModel.CanLaunch.",
            "nullable": true
          },
          "contactLimit": {
            "type": "integer",
            "description": "The sending estimate counts are null when the estimate cannot be computed (see the `sending_estimate_unavailable` warning).",
            "format": "int32",
            "nullable": true
          },
          "contactLimitPeriod": {
            "type": "string",
            "description": "DEV-3765: `month` when Ken.Scraper.API.Canonical.LaunchReadinessModel.ContactLimit and the counts below cover one month, else `total`.",
            "nullable": true
          },
          "emailStepCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "totalEmailCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "dailySendingLimit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "estimatedDayCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "forecast": {
            "$ref": "#/components/schemas/LaunchForecastModel"
          }
        },
        "additionalProperties": false
      },
      "LaunchReadinessReasonModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "fixUrl": {
            "type": "string",
            "nullable": true
          },
          "kinds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-6992: approval_required and approval_will_be_requested only, the kinds the launch waits on (copy, lead_list, ...). Omitted elsewhere.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInAccountHealthModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`healthy` or `low_acceptance` (below 20% on at least 40 invites; back at 25%). Low caps invites at 5 a day.",
            "nullable": true
          },
          "acceptRate": {
            "type": "number",
            "description": "Accepted over sent, a fraction from 0 to 1. Omitted when Ken.Scraper.API.Canonical.LinkedInAccountHealthModel.Sample is 0.",
            "format": "double",
            "nullable": true
          },
          "sample": {
            "type": "integer",
            "description": "Invites sent 3 to 30 days ago.",
            "format": "int32"
          },
          "changedAt": {
            "type": "string",
            "description": "When Ken.Scraper.API.Canonical.LinkedInAccountHealthModel.Status last changed. Omitted when it never changed.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInAccountModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "publicIdentifier": {
            "type": "string",
            "nullable": true
          },
          "profileUrl": {
            "type": "string",
            "nullable": true
          },
          "profileImageUrl": {
            "type": "string",
            "nullable": true
          },
          "headline": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "timezone": {
            "type": "string",
            "nullable": true
          },
          "workingHours": {
            "type": "string",
            "nullable": true
          },
          "dailyInviteCap": {
            "type": "integer",
            "format": "int32"
          },
          "dailyMessageCap": {
            "type": "integer",
            "format": "int32"
          },
          "dailyVisitCap": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdDatetime": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "unipileAccountId": {
            "type": "string",
            "nullable": true
          },
          "statusChangedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "invitesToday": {
            "type": "integer",
            "description": "Invites sent today, on the seat's own day (the trailing 24 hours when rolling seat budgets are on).\nCompare with Ken.Scraper.API.Canonical.LinkedInAccountModel.DailyInviteCap. Omitted when the counters could not be read (DEV-2026).",
            "format": "int32",
            "nullable": true
          },
          "messagesToday": {
            "type": "integer",
            "description": "Messages and InMails sent today, on the same day as Ken.Scraper.API.Canonical.LinkedInAccountModel.InvitesToday.",
            "format": "int32",
            "nullable": true
          },
          "visitsToday": {
            "type": "integer",
            "description": "Profile visits today, on the same day as Ken.Scraper.API.Canonical.LinkedInAccountModel.InvitesToday.",
            "format": "int32",
            "nullable": true
          },
          "invitesSent30d": {
            "type": "integer",
            "description": "Invites sent in the last 30 days (by invite time). Omitted when it could not be read.",
            "format": "int32",
            "nullable": true
          },
          "acceptRate": {
            "type": "number",
            "description": "Share of Ken.Scraper.API.Canonical.LinkedInAccountModel.InvitesSent30d that were accepted, a fraction from 0 to 1. Omitted when no\ninvite was sent in the window.",
            "format": "double",
            "nullable": true
          },
          "usedBy": {
            "$ref": "#/components/schemas/UsedByModel"
          },
          "lastActionAt": {
            "type": "string",
            "description": "When the seat last completed an outbound action: the newest confirmed campaign step or Accounts-lane touch\n(DEV-3977). A person's replies from the Inbox do not count. Omitted when the seat has none or it could not be\nread.",
            "format": "date-time",
            "nullable": true
          },
          "lastActionType": {
            "type": "string",
            "description": "The action at Ken.Scraper.API.Canonical.LinkedInAccountModel.LastActionAt: `visit`, `invite`, `message`, `inmail`,\n`withdraw`, `follow`, `reaction`, `comment` or `endorse`. Omitted with it.",
            "nullable": true
          },
          "pausedAt": {
            "type": "string",
            "description": "When a member paused the account, or null when it is not paused. A paused account sends no outreach\n(invites, messages, InMails, profile visits, withdrawals, approved Accounts notes); it waits and continues on\nresume, and so do the autonomous reply agent's sends. A person's replies from the Inbox and inbox sync keep\nrunning. Independent of `status`.",
            "format": "date-time",
            "nullable": true
          },
          "connectedByMemberId": {
            "type": "integer",
            "description": "The member who connected the seat. Touches that send from it wait on this member's approval\n(DEV-1811); null for a seat connected before that was recorded.",
            "format": "int64",
            "nullable": true
          },
          "importConnections": {
            "type": "boolean",
            "description": "The seat's connections are imported into Accounts as people and accounts (DEV-5778). Only the member who\nconnected the seat or a workspace admin switches it. Always present."
          },
          "importConnectionsChangedAt": {
            "type": "string",
            "description": "When importConnections last changed. Omitted while it never did.",
            "format": "date-time",
            "nullable": true
          },
          "workingHoursSchedule": {
            "$ref": "#/components/schemas/LinkedInWeeklySchedule"
          },
          "products": {
            "$ref": "#/components/schemas/LinkedInAccountProductsModel"
          },
          "invitesLast7Days": {
            "type": "integer",
            "description": "Invites sent in the last 7 days, against Ken.Scraper.API.Canonical.LinkedInAccountModel.WeeklyInviteCap (DEV-1295). The safety fields are omitted together when they could not be read.",
            "format": "int32",
            "nullable": true
          },
          "weeklyInviteCap": {
            "type": "integer",
            "description": "Rolling 7-day invite cap, at most 100.",
            "format": "int32",
            "nullable": true
          },
          "pendingInvites": {
            "type": "integer",
            "description": "Invitations still pending: the larger of Kenso's own and Unipile's count.",
            "format": "int32",
            "nullable": true
          },
          "pendingInviteCap": {
            "type": "integer",
            "description": "At or above this many pending invitations the seat sends no new invites.",
            "format": "int32",
            "nullable": true
          },
          "health": {
            "$ref": "#/components/schemas/LinkedInAccountHealthModel"
          },
          "rampStage": {
            "type": "integer",
            "description": "Ramp stage (0, 1, 2, then full).",
            "format": "int32",
            "nullable": true
          },
          "rampInviteCap": {
            "type": "integer",
            "description": "Today's invite cap from the ramp: 5, 10, 20, then the seat's daily invite cap.",
            "format": "int32",
            "nullable": true
          },
          "safetyEnabled": {
            "type": "boolean",
            "description": "False while Kenso shows the safety values but does not enforce the weekly, pending and low-acceptance caps yet.",
            "nullable": true
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Ids of this workspace's tags on the account, ascending; empty when it has none (DEV-4051). Set them with\n`POST /v1/tags/{tagId}/assignments` and `entityType: linkedin_account`. Only\n`GET /v1/linkedin-accounts`, `GET /v1/linkedin-accounts/{linkedinAccountId}` and its `PATCH`\ncarry it, and they omit it when the tags could not be read. Other lists of this model, such as a campaign's\nLinkedIn accounts, never carry it.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInAccountProductsModel": {
        "type": "object",
        "properties": {
          "premium": {
            "type": "boolean"
          },
          "salesNavigator": {
            "type": "boolean"
          },
          "recruiter": {
            "type": "boolean"
          },
          "checkedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "LinkedInConnectSessionModel": {
        "type": "object",
        "properties": {
          "linkedInAccountId": {
            "type": "integer",
            "format": "int64"
          },
          "url": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInEngagementActorModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "headline": {
            "type": "string",
            "nullable": true
          },
          "profileUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInEngagementModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "description": "post_reaction, post_comment, post_reply or profile_view.",
            "nullable": true
          },
          "postUrl": {
            "type": "string",
            "nullable": true
          },
          "actor": {
            "$ref": "#/components/schemas/LinkedInEngagementActorModel"
          },
          "commentText": {
            "type": "string",
            "nullable": true
          },
          "reactionType": {
            "type": "string",
            "description": "like, celebrate, support, love, insightful or funny; reactions only.",
            "nullable": true
          },
          "commentId": {
            "type": "string",
            "description": "LinkedIn's id of the comment or reply.",
            "nullable": true
          },
          "parentCommentId": {
            "type": "string",
            "description": "The comment a reply answers; set on post_reply only.",
            "nullable": true
          },
          "postText": {
            "type": "string",
            "description": "The text of the post that was engaged with, cut at 2,000 characters.",
            "nullable": true
          },
          "intent": {
            "type": "string",
            "description": "positive, requesting, question, neutral or negative: Jev's label of a comment or reply; null until classified and on reactions.",
            "nullable": true
          },
          "intentReason": {
            "type": "string",
            "description": "Jev's one-line reason for the intent label.",
            "nullable": true
          },
          "ownPost": {
            "type": "boolean",
            "description": "False when the post is a pasted third-party post (its author is not a seat or company page of the workspace)."
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "firstSeenAt": {
            "type": "string",
            "format": "date-time"
          },
          "status": {
            "type": "string",
            "description": "new, imported, offered (a workflow run took it; no contact) or skipped.",
            "nullable": true
          },
          "skipReason": {
            "type": "string",
            "description": "When skipped: own_seat, kind_filtered, reaction_type_filtered, keyword_mismatch, intent_filtered, or not_imported\n(the intake created no contact).",
            "nullable": true
          },
          "contactId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One stored LinkedIn engagement of a LinkedIn signal trigger (DEV-1297)."
      },
      "LinkedInSequenceModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LinkedInSequenceStepModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInSequenceSnapshotStepModel": {
        "type": "object",
        "properties": {
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "stepType": {
            "type": "string",
            "nullable": true
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "waitDays": {
            "type": "integer",
            "format": "int32"
          },
          "anchorEmailStepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "positionInGap": {
            "type": "integer",
            "format": "int32"
          },
          "conditionType": {
            "type": "string",
            "nullable": true
          },
          "conditionScopeStepOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isOptional": {
            "type": "boolean"
          },
          "openProfileOnly": {
            "type": "boolean"
          },
          "isActive": {
            "type": "boolean"
          },
          "noteMode": {
            "type": "string",
            "description": "template (the body is the note) or ai (Ken writes each note).",
            "nullable": true
          },
          "aiInstructions": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInSequenceStepModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "stepType": {
            "type": "string",
            "nullable": true
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "waitDays": {
            "type": "integer",
            "format": "int32"
          },
          "anchorEmailStepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "positionInGap": {
            "type": "integer",
            "format": "int32"
          },
          "conditionType": {
            "type": "string",
            "nullable": true
          },
          "conditionScopeStepOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isOptional": {
            "type": "boolean"
          },
          "openProfileOnly": {
            "type": "boolean"
          },
          "isActive": {
            "type": "boolean"
          },
          "noteMode": {
            "type": "string",
            "description": "template (the body is the note) or ai (Ken writes each note).",
            "nullable": true
          },
          "aiInstructions": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInSequenceVersionDetailModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByEmail": {
            "type": "string",
            "nullable": true
          },
          "isRevert": {
            "type": "boolean"
          },
          "revertedFromVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "revertedFromVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "revertedFromCreatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LinkedInSequenceSnapshotStepModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInSequenceVersionSaveModel": {
        "type": "object",
        "properties": {
          "sequence": {
            "$ref": "#/components/schemas/LinkedInSequenceModel"
          },
          "version": {
            "$ref": "#/components/schemas/SequenceVersionModel"
          },
          "versionWarning": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LinkedInSettingsModel": {
        "type": "object",
        "properties": {
          "isEnabled": {
            "type": "boolean"
          },
          "channelPolicy": {
            "type": "string",
            "nullable": true
          },
          "notAcceptedAfterDays": {
            "type": "integer",
            "format": "int32"
          },
          "conditionWaitDays": {
            "type": "integer",
            "format": "int32"
          },
          "isWithdrawEnabled": {
            "type": "boolean"
          },
          "stopLinkedInOnEmailReply": {
            "type": "boolean"
          },
          "stopEmailOnLinkedInReply": {
            "type": "boolean"
          },
          "stopSequenceForCompanyOnReply": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "LinkedInWeeklySchedule": {
        "type": "object",
        "properties": {
          "mon": {
            "$ref": "#/components/schemas/LinkedInWorkingDay"
          },
          "tue": {
            "$ref": "#/components/schemas/LinkedInWorkingDay"
          },
          "wed": {
            "$ref": "#/components/schemas/LinkedInWorkingDay"
          },
          "thu": {
            "$ref": "#/components/schemas/LinkedInWorkingDay"
          },
          "fri": {
            "$ref": "#/components/schemas/LinkedInWorkingDay"
          },
          "sat": {
            "$ref": "#/components/schemas/LinkedInWorkingDay"
          },
          "sun": {
            "$ref": "#/components/schemas/LinkedInWorkingDay"
          }
        },
        "additionalProperties": false
      },
      "LinkedInWorkingDay": {
        "type": "object",
        "properties": {
          "open": {
            "type": "boolean",
            "nullable": true
          },
          "start": {
            "type": "string",
            "nullable": true
          },
          "end": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LintEmailCopyRequest": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string",
            "description": "The step's subject line. Empty fails `subject_length`.",
            "nullable": true
          },
          "body": {
            "type": "string",
            "description": "The step's body, plain text or the editor's HTML. Required, at most 20,000 characters.",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "description": "The step's position: 1 (the default) is the first email, 2 and up are follow-ups.",
            "format": "int32",
            "nullable": true
          },
          "variables": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Each AI variable name that has a personalization prompt (`First Line`). Omit it to skip the AI variable\ncoverage rule.",
            "nullable": true
          },
          "customVariableKeys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The campaign's registered custom variable keys (`industry_note`). A `{key}` merge field passes only when\nits key is listed, matched as the sequence save matches it.",
            "nullable": true
          },
          "isFinanceVertical": {
            "type": "boolean",
            "description": "True when the client is in finance, insurance, real estate or lending: insurance, mortgage, loans, investment\nand rates then do not count toward the body's MEDIUM spam budget. Defaults to false.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ListCheckBounce": {
        "type": "object",
        "properties": {
          "expected": {
            "type": "number",
            "format": "double"
          },
          "beforeFixes": {
            "type": "number",
            "format": "double"
          },
          "band": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ListCheckBucket": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListCheckSample"
            },
            "nullable": true
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ListCheckContacted": {
        "type": "object",
        "properties": {
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "days": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "skipByDefault": {
            "type": "boolean"
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListCheckSample"
            },
            "nullable": true
          },
          "rows": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ListCheckItem": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "fixLabel": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          },
          "defaultOn": {
            "type": "boolean"
          },
          "prior": {
            "type": "number",
            "format": "double"
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ListCheckSample"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ListCheckSample": {
        "type": "object",
        "properties": {
          "row": {
            "type": "integer",
            "format": "int32"
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ListCheckShare": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "nullable": true
          },
          "share": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "LogicalOperatorEnum": {
        "enum": [
          0,
          1
        ],
        "type": "integer",
        "format": "int32"
      },
      "LongRange": {
        "type": "object",
        "properties": {
          "min": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "max": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "LookalikeSeedListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/LookalikeSeedModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/SearchListPagination"
          }
        },
        "additionalProperties": false,
        "description": "`GET /v1/search/lookalike-seeds`: every suggestion in one page (up to 200), so `pagination.hasMore` is\n            always false and `nextCursor` null."
      },
      "LookalikeSeedModel": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "description": "The company's registrable domain, e.g. `acme.com`. Send it as a `{\"domain\": ...}` seed.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "description": "The company's name as the workspace knows it. Omitted when unknown.",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "description": "Deals at the stage asked for (`crm`, `crm_won`), distinct Interested contacts (`interested`),\ndistinct replying contacts (`replies`), the campaign's contacts at the company (`campaign`), visits\n(`website_visitors`), or customer accounts with the domain, normally 1 (`customers`).",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "One seed suggestion for a lookalike search (DEV-6968)."
      },
      "MailProviderCountModel": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "MarkAllThreadsReadModel": {
        "type": "object",
        "properties": {
          "updatedCount": {
            "type": "integer",
            "description": "Email messages and LinkedIn conversations changed. A repeat call returns 0.",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "MarketColdEmailRegimeEnum": {
        "enum": [
          "opt_out",
          "consent",
          "unresolved"
        ],
        "type": "string"
      },
      "MarketCountry": {
        "required": [
          "coldEmail",
          "iso2",
          "languages",
          "name"
        ],
        "type": "object",
        "properties": {
          "iso2": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketCountryLanguage"
            },
            "nullable": true
          },
          "coldEmail": {
            "$ref": "#/components/schemas/MarketCountryColdEmail"
          }
        },
        "additionalProperties": false
      },
      "MarketCountryColdEmail": {
        "type": "object",
        "properties": {
          "regime": {
            "$ref": "#/components/schemas/MarketColdEmailRegimeEnum"
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "requiresAcknowledgement": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "MarketCountryLanguage": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "locale": {
            "type": "string",
            "nullable": true
          },
          "share": {
            "type": "number",
            "format": "double"
          },
          "official": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "MarketModel": {
        "required": [
          "pack"
        ],
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "nullable": true
          },
          "language": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/MarketPackStatusEnum"
          },
          "pack": {
            "$ref": "#/components/schemas/MarketPack"
          },
          "countries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketCountry"
            },
            "description": "The countries of the pack, each with its languages and cold email notes. Every note ends with \"Not legal advice.\"",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-15: one market pack with the cold email notes of its countries (`GET /v1/markets/{locale}`)."
      },
      "MarketPack": {
        "required": [
          "bannedPhrases",
          "direction",
          "examples",
          "formality",
          "language",
          "locale",
          "name",
          "nameOrder",
          "oooPhrases",
          "optOutPhrases",
          "primary",
          "salutations",
          "signOffs",
          "spamPhrases",
          "status",
          "stopwords",
          "style",
          "text",
          "version"
        ],
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "nullable": true
          },
          "language": {
            "type": "string",
            "nullable": true
          },
          "primary": {
            "type": "boolean"
          },
          "version": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/MarketPackStatusEnum"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "direction": {
            "type": "string",
            "nullable": true
          },
          "formality": {
            "$ref": "#/components/schemas/MarketPackFormality"
          },
          "salutations": {
            "$ref": "#/components/schemas/MarketPackSalutations"
          },
          "signOffs": {
            "$ref": "#/components/schemas/MarketPackSignOffs"
          },
          "nameOrder": {
            "type": "string",
            "nullable": true
          },
          "style": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "bannedPhrases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "spamPhrases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "stopwords": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "text": {
            "$ref": "#/components/schemas/MarketPackText"
          },
          "oooPhrases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "optOutPhrases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "examples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MarketPackExample"
            },
            "nullable": true
          },
          "eval": {
            "$ref": "#/components/schemas/MarketPackEval"
          }
        },
        "additionalProperties": false
      },
      "MarketPackEval": {
        "type": "object",
        "properties": {
          "writerModel": {
            "type": "string",
            "nullable": true
          },
          "judgeModels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "judgeThreshold": {
            "type": "number",
            "format": "double"
          },
          "testedAt": {
            "type": "string",
            "nullable": true
          },
          "results": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MarketPackExample": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MarketPackFormality": {
        "type": "object",
        "properties": {
          "default": {
            "type": "string",
            "nullable": true
          },
          "pronouns": {
            "$ref": "#/components/schemas/MarketPackPronouns"
          }
        },
        "additionalProperties": false
      },
      "MarketPackPronouns": {
        "type": "object",
        "properties": {
          "formal": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "informal": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MarketPackSalutations": {
        "type": "object",
        "properties": {
          "formal": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "informal": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "unknownGender": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MarketPackSignOffs": {
        "type": "object",
        "properties": {
          "formal": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "informal": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MarketPackStatusEnum": {
        "enum": [
          "draft",
          "supported",
          "tested"
        ],
        "type": "string"
      },
      "MarketPackText": {
        "type": "object",
        "properties": {
          "quoteLine": {
            "type": "string",
            "nullable": true
          },
          "quoteDate": {
            "type": "string",
            "nullable": true
          },
          "unsubscribeLink": {
            "type": "string",
            "nullable": true
          },
          "unsubscribePageTitle": {
            "type": "string",
            "nullable": true
          },
          "unsubscribePage": {
            "$ref": "#/components/schemas/MarketPackUnsubscribePage"
          }
        },
        "additionalProperties": false
      },
      "MarketPackUnsubscribePage": {
        "type": "object",
        "properties": {
          "confirmTitle": {
            "type": "string",
            "nullable": true
          },
          "confirmBody": {
            "type": "string",
            "nullable": true
          },
          "button": {
            "type": "string",
            "nullable": true
          },
          "doneTitle": {
            "type": "string",
            "nullable": true
          },
          "doneBody": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MarketSummaryModel": {
        "type": "object",
        "properties": {
          "locale": {
            "type": "string",
            "description": "BCP 47 locale (`fr-FR`).",
            "nullable": true
          },
          "language": {
            "type": "string",
            "description": "ISO 639-1 code (`fr`).",
            "nullable": true
          },
          "name": {
            "type": "string",
            "description": "The locale's name in its own language (`Français (France)`).",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/MarketPackStatusEnum"
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "ISO-2 codes of the countries one of whose official languages this pack writes, sorted.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-15: one market pack in `GET /v1/markets`."
      },
      "MeModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "description": "admin, member, view_only, client, or super_admin.",
            "nullable": true
          },
          "isSuperAdmin": {
            "type": "boolean"
          },
          "isActive": {
            "type": "boolean"
          },
          "linkedinUrl": {
            "type": "string",
            "nullable": true
          },
          "jobTitle": {
            "type": "string",
            "description": "The caller's job title. Omitted when unset.",
            "nullable": true
          },
          "timeZone": {
            "type": "string",
            "description": "IANA time zone id, for example `America/New_York`. Omitted when unset. The member's app time zone: Today, calls,\nnav counts and, after the daily brief's own zone, notifications use it (DEV-3913).",
            "nullable": true
          },
          "language": {
            "type": "string",
            "description": "The caller's language, a BCP 47 tag such as `fr` or `fr-FR`. Omitted when unset; null means en.",
            "nullable": true
          },
          "profileImageUrl": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "deletionDueAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "workspaces": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeWorkspaceModel"
            },
            "nullable": true
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Feature flag keys that are on for the caller in the workspace from `X-Ken-Workspace-Id`\n(or the caller's only workspace), sorted ascending. Always present; empty when nothing is on.",
            "nullable": true
          },
          "permissions": {
            "$ref": "#/components/schemas/MePermissionsModel"
          },
          "hasPaidPlan": {
            "type": "boolean",
            "description": "Whether the workspace Ken.Scraper.API.Canonical.MeModel.Features uses is on a paid plan: an Active or Trialing plan other than\nFree (a white-label child reads its master's). Always present; null for staff, when there is no workspace, or\nwhen the plan could not be read (DEV-5245).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The caller. One shape for `GET /v1/me` and `PATCH /v1/me`."
      },
      "MePermissionTemplateModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Null for a built-in the workspace has never edited.",
            "format": "int64",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "builtIn": {
            "type": "string",
            "description": "admin, editor, viewer, or client. Null for a custom template.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MePermissionsModel": {
        "type": "object",
        "properties": {
          "workspaceId": {
            "type": "integer",
            "format": "int64"
          },
          "template": {
            "$ref": "#/components/schemas/MePermissionTemplateModel"
          },
          "pages": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "All eleven pages: off, view, or edit.",
            "nullable": true
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "accountScope": {
            "type": "string",
            "description": "all or own.",
            "nullable": true
          },
          "monthlyCreditLimit": {
            "type": "integer",
            "description": "Credits per calendar month (UTC). Null is no limit; 0 cannot spend.",
            "format": "int64",
            "nullable": true
          },
          "creditsUsedThisMonth": {
            "type": "integer",
            "description": "Whole credits the caller spent in this workspace this calendar month (UTC).",
            "format": "int64"
          }
        },
        "additionalProperties": false,
        "description": "Effective permissions in one workspace. Pages and features use catalog order and wire names."
      },
      "MeWorkspaceModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "description": "admin, member, view_only, or client.",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "description": "The square Icon. Omitted when none.",
            "nullable": true
          },
          "wordmarkUrl": {
            "type": "string",
            "description": "DEV-4548: the wide Logo (wordmark). Omitted when none.",
            "nullable": true
          },
          "parentWorkspaceId": {
            "type": "integer",
            "description": "The white-label master of this workspace. Omitted for a master.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MeetingBriefAttendeeModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "committeeRole": {
            "type": "string",
            "description": "champion, economic_buyer, approver, evaluator, user, executive_sponsor, blocker or unknown; omitted when not on the committee.",
            "nullable": true
          },
          "isNew": {
            "type": "boolean",
            "description": "No earlier meeting of the account had this guest."
          },
          "personId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "stakeholderId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "response": {
            "type": "string",
            "description": "yes, maybe, no or awaiting.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One guest on the meeting, the owner left out."
      },
      "MeetingBriefLineModel": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "nullable": true
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingBriefSourceModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One line of the brief and the sources it rests on."
      },
      "MeetingBriefRelationshipModel": {
        "type": "object",
        "properties": {
          "stage": {
            "type": "string",
            "nullable": true
          },
          "touches": {
            "type": "integer",
            "format": "int32"
          },
          "replies": {
            "type": "integer",
            "format": "int32"
          },
          "firstContactAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastTouchAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The account relationship, counted from data."
      },
      "MeetingBriefSectionsModel": {
        "type": "object",
        "properties": {
          "openWith": {
            "$ref": "#/components/schemas/MeetingBriefLineModel"
          },
          "attending": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingBriefAttendeeModel"
            },
            "nullable": true
          },
          "gotTheYes": {
            "$ref": "#/components/schemas/MeetingBriefLineModel"
          },
          "relationship": {
            "$ref": "#/components/schemas/MeetingBriefRelationshipModel"
          },
          "whyNow": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingBriefLineModel"
            },
            "description": "Signals from the last 90 days.",
            "nullable": true
          },
          "angle": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingBriefLineModel"
            },
            "description": "Two or three talking points.",
            "nullable": true
          },
          "openItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingBriefLineModel"
            },
            "description": "Commitments and unanswered questions.",
            "nullable": true
          },
          "touchHistory": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingBriefTouchModel"
            },
            "description": "Listed from data, newest first.",
            "nullable": true
          },
          "dataNote": {
            "type": "string",
            "description": "Said when data is thin, such as \"No outbound history yet; this is from the account's research.\"",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The brief's sections. Attending, relationship and touchHistory come from Kenso's data; the other lines are written by the model, each with its sources."
      },
      "MeetingBriefSourceModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "touch, email, signal, person, account, research or workspace.",
            "nullable": true
          },
          "id": {
            "type": "string",
            "description": "The source's id: a touch, signal, person, account or workspace id as a string, or the msg_ id of an email.",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "An outside link, for research claims and signals that have one.",
            "nullable": true
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Where a line comes from."
      },
      "MeetingBriefTouchModel": {
        "type": "object",
        "properties": {
          "at": {
            "type": "string",
            "format": "date-time"
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "direction": {
            "type": "string",
            "description": "outbound or inbound.",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "personName": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "$ref": "#/components/schemas/MeetingBriefSourceModel"
          }
        },
        "additionalProperties": false,
        "description": "One row of the touch history."
      },
      "MeetingClientBriefModel": {
        "type": "object",
        "properties": {
          "meetingId": {
            "type": "string",
            "description": "mtg_ id.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "ready, not_written or not_eligible.",
            "nullable": true
          },
          "ineligibleReason": {
            "type": "string",
            "description": "Why the meeting gets no brief: not_account_meeting, no_owner, cancelled, owner_declined, no_external_guest, too_many_guests, already_started. Omitted while the meeting qualifies.",
            "nullable": true
          },
          "version": {
            "type": "integer",
            "description": "0 until the first brief is written; one more on each rewrite.",
            "format": "int32"
          },
          "writtenAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "language": {
            "type": "string",
            "description": "The language the brief is written in, such as en.",
            "nullable": true
          },
          "authorSource": {
            "type": "string",
            "description": "ken, agent or user; omitted until it is written.",
            "nullable": true
          },
          "staleSince": {
            "type": "string",
            "description": "The account's first activity after writtenAt.",
            "format": "date-time",
            "nullable": true
          },
          "isStale": {
            "type": "boolean"
          },
          "sections": {
            "$ref": "#/components/schemas/MeetingBriefSectionsModel"
          }
        },
        "additionalProperties": false,
        "description": "meetings.get-client-brief data (DEV-5204): the brief a client seat may read, and what meetings.get-brief answers a client\nseat. The Ken.Scraper.API.Canonical.MeetingBriefModel fields without the credit state (creditsCharged, writeBlockedReason), the write\nand refresh state (canWrite, canRefresh) and the model's name; every field keeps its MeetingBriefModel name and type."
      },
      "MeetingRepNotesCurrentModel": {
        "type": "object",
        "properties": {
          "repNotes": {
            "type": "string",
            "description": "Your typed notes as stored now; empty before your first save.",
            "nullable": true
          },
          "repNotesVersion": {
            "type": "integer",
            "description": "Their version: send it as baseVersion when you save again.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "The stored rep notes on a notes save's 409 version_conflict (DEV-7263)."
      },
      "MeetingTypeHostModel": {
        "type": "object",
        "properties": {
          "memberId": {
            "type": "integer",
            "format": "int64"
          },
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "position": {
            "type": "integer",
            "format": "int32"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "isOrganizer": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "MeetingTypeModel": {
        "type": "object",
        "properties": {
          "lengthMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "locationKind": {
            "type": "string",
            "nullable": true
          },
          "locationDetail": {
            "type": "string",
            "nullable": true
          },
          "minimumNoticeMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "bookingWindowDays": {
            "type": "integer",
            "format": "int32"
          },
          "bufferBeforeMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "bufferAfterMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "dailyCap": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "reminderEnabled": {
            "type": "boolean"
          },
          "reminderText": {
            "type": "string",
            "nullable": true
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingTypeQuestion"
            },
            "nullable": true
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isSecret": {
            "type": "boolean"
          },
          "isEnabled": {
            "type": "boolean"
          },
          "isDefault": {
            "type": "boolean"
          },
          "availability": {
            "$ref": "#/components/schemas/AvailabilityScheduleModel"
          },
          "hosts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingTypeHostModel"
            },
            "nullable": true
          },
          "hostsNote": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "MeetingTypeQuestion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "required": {
            "type": "boolean"
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MeetingTypeQuestionInput": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "required": {
            "type": "boolean",
            "nullable": true
          },
          "options": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MeetingTypeSlotModel": {
        "type": "object",
        "properties": {
          "startAt": {
            "type": "string",
            "format": "date-time"
          },
          "endAt": {
            "type": "string",
            "format": "date-time"
          },
          "localStartAt": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MeetingTypeSlotsModel": {
        "type": "object",
        "properties": {
          "meetingTypeId": {
            "type": "integer",
            "format": "int64"
          },
          "hostMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "lengthMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "timeZone": {
            "type": "string",
            "nullable": true
          },
          "hostTimeZone": {
            "type": "string",
            "nullable": true
          },
          "slots": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingTypeSlotModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MemberPermissionTemplateModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Null for a built-in the workspace has never edited.",
            "format": "int64",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "builtIn": {
            "type": "string",
            "description": "`admin`, `editor`, `viewer` or `client`; null for a custom template.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "MemberPermissionsModel": {
        "type": "object",
        "properties": {
          "template": {
            "$ref": "#/components/schemas/MemberPermissionTemplateModel"
          },
          "overrides": {
            "$ref": "#/components/schemas/PermissionOverridesModel"
          },
          "effective": {
            "$ref": "#/components/schemas/PermissionSetModel"
          },
          "changeCount": {
            "type": "integer",
            "description": "How many rows differ from the template.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A member's template, overrides and effective permissions."
      },
      "MessageAttachmentModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The `att_` id `GET /v1/attachments/{attachmentId}/content` downloads. Omitted when Kenso cannot serve\nthe file (older messages whose original email Kenso did not store).",
            "nullable": true
          },
          "fileName": {
            "type": "string",
            "nullable": true
          },
          "contentType": {
            "type": "string",
            "nullable": true
          },
          "sizeBytes": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "isInline": {
            "type": "boolean",
            "description": "True for a part the email shows in its body, such as an inline image."
          },
          "contentId": {
            "type": "string",
            "description": "The MIME Content-ID an HTML body's `cid:` image refers to, without the `cid:` scheme.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-4082: a file on a thread message, inline images included."
      },
      "MoneyModel": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "integer",
            "format": "int64"
          },
          "currency": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "OutboundSiteModel": {
        "type": "object",
        "properties": {
          "mainSiteUrl": {
            "type": "string",
            "nullable": true
          },
          "effectiveMainSiteUrl": {
            "type": "string",
            "nullable": true
          },
          "brandName": {
            "type": "string",
            "nullable": true
          },
          "contactEmail": {
            "type": "string",
            "nullable": true
          },
          "legalName": {
            "type": "string",
            "nullable": true
          },
          "postalAddress": {
            "type": "string",
            "nullable": true
          },
          "showMainSiteLink": {
            "type": "boolean"
          },
          "currentVersion": {
            "$ref": "#/components/schemas/OutboundSiteVersionModel"
          },
          "latestRun": {
            "$ref": "#/components/schemas/OutboundSiteRunModel"
          }
        },
        "additionalProperties": false
      },
      "OutboundSitePreviewLink": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "OutboundSiteRunModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "trigger": {
            "type": "string",
            "nullable": true
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "versionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "requestedByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "finishedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "OutboundSiteVersionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "note": {
            "type": "string",
            "nullable": true
          },
          "htmlBytes": {
            "type": "integer",
            "format": "int64"
          },
          "assetBytes": {
            "type": "integer",
            "format": "int64"
          },
          "rounds": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "isBelowThreshold": {
            "type": "boolean"
          },
          "isCurrent": {
            "type": "boolean"
          },
          "runId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "OutreachFormalityEnum": {
        "enum": [
          "formal",
          "informal"
        ],
        "type": "string"
      },
      "OutreachLanguageSourceEnum": {
        "enum": [
          "manual",
          "reply",
          "declared",
          "country",
          "hq",
          "default"
        ],
        "type": "string"
      },
      "PatchWorkspaceRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "linkedinCompanyUrl": {
            "type": "string",
            "nullable": true
          },
          "companyContext": {
            "type": "string",
            "nullable": true
          },
          "pauseSendingOnUsHolidays": {
            "type": "boolean",
            "nullable": true
          },
          "replyTo": {
            "type": "string",
            "description": "DEV-2528: the workspace's Reply-To. A live mailbox connected to this workspace that Kenso reads replies from\n(not a member's own mailbox). Null or empty clears it.",
            "nullable": true
          },
          "replyRateBenchmark": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "replyRateTarget": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "positiveReplyRateBenchmark": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "positiveReplyRateTarget": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "meetingsPerMonthBenchmark": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "meetingsPerMonthTarget": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PermissionOverridesModel": {
        "type": "object",
        "properties": {
          "pages": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "features": {
            "type": "object",
            "additionalProperties": {
              "type": "boolean"
            },
            "nullable": true
          },
          "accountScope": {
            "type": "string",
            "description": "`all` or `own`; null = the template's scope.",
            "nullable": true
          },
          "credits": {
            "$ref": "#/components/schemas/CreditLimitOverrideModel"
          }
        },
        "additionalProperties": false,
        "description": "Only the differences from the template."
      },
      "PermissionSetModel": {
        "type": "object",
        "properties": {
          "pages": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "All eleven pages: `off`, `view` or `edit`.",
            "nullable": true
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "accountScope": {
            "type": "string",
            "description": "`all` or `own`.",
            "nullable": true
          },
          "monthlyCreditLimit": {
            "type": "integer",
            "description": "Credits per calendar month (UTC); null = no limit, 0 = cannot spend.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PermissionTemplateModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "builtIn": {
            "type": "string",
            "description": "`admin`, `editor`, `viewer` or `client`; null for a custom template.",
            "nullable": true
          },
          "locked": {
            "type": "boolean",
            "description": "True for the Admin template, which cannot be edited or deleted."
          },
          "pages": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "description": "All eleven pages: `off`, `view` or `edit`.",
            "nullable": true
          },
          "features": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The features that are on, in catalog order.",
            "nullable": true
          },
          "accountScope": {
            "type": "string",
            "description": "`all` or `own`.",
            "nullable": true
          },
          "monthlyCreditLimit": {
            "type": "integer",
            "description": "Credits per calendar month (UTC); null = no limit, 0 = cannot spend.",
            "format": "int64",
            "nullable": true
          },
          "memberCount": {
            "type": "integer",
            "description": "Active members on the template.",
            "format": "int32"
          },
          "pageCount": {
            "type": "integer",
            "description": "Pages that are not off.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "A permission template (DEV-1654). Wire names follow the permission catalog."
      },
      "PersonAccountModel": {
        "required": [
          "name",
          "role"
        ],
        "type": "object",
        "properties": {
          "accountId": {
            "type": "integer",
            "format": "int64"
          },
          "stakeholderId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "primaryDomain": {
            "type": "string",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "nullable": true
          },
          "role": {
            "type": "string",
            "nullable": true
          },
          "priority": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "coverage": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonEmailFindSummaryModel": {
        "required": [
          "status"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "fromKenPool": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonImportJobModel": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "description": "Where the rows came from: `csv`, `search`, `google_sheets`, and the other import sources.",
            "nullable": true
          },
          "createdCount": {
            "type": "integer",
            "format": "int32"
          },
          "updatedCount": {
            "type": "integer",
            "format": "int32"
          },
          "skippedCount": {
            "type": "integer",
            "format": "int32"
          },
          "startedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Counts of a `contact_import` job with target people (DEV-3358): each row created a person, updated (matched) one, or\nwas skipped (no email, LinkedIn URL, or name with a business company domain, or intake refused it)."
      },
      "PersonIntakeModel": {
        "required": [
          "matchedBy",
          "person"
        ],
        "type": "object",
        "properties": {
          "person": {
            "$ref": "#/components/schemas/PersonModel"
          },
          "created": {
            "type": "boolean"
          },
          "matchedBy": {
            "type": "string",
            "nullable": true
          },
          "accountId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "accountCreated": {
            "type": "boolean"
          },
          "suggestedDuplicateOfPersonId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "emailDropped": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonModel": {
        "required": [
          "createdBy",
          "pinnedFields",
          "updatedBy"
        ],
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "linkedinUrl": {
            "type": "string",
            "nullable": true
          },
          "kenPersonId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "leadStatus": {
            "type": "string",
            "nullable": true
          },
          "leadStatusAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "score": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "phones": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PersonPhoneModel"
            },
            "nullable": true
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "phoneOptOutAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "firstSource": {
            "$ref": "#/components/schemas/PersonSourceModel"
          },
          "latestSource": {
            "$ref": "#/components/schemas/PersonSourceModel"
          },
          "headline": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "seniority": {
            "type": "string",
            "nullable": true
          },
          "department": {
            "type": "string",
            "nullable": true
          },
          "photoUrl": {
            "type": "string",
            "nullable": true
          },
          "photoSource": {
            "type": "string",
            "nullable": true
          },
          "profileSource": {
            "type": "string",
            "nullable": true
          },
          "profileEnrichedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "profile": {
            "$ref": "#/components/schemas/PersonProfileModel"
          },
          "pinnedFields": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "createdBy": {
            "$ref": "#/components/schemas/ActorModel"
          },
          "updatedBy": {
            "$ref": "#/components/schemas/ActorModel"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "emailFind": {
            "$ref": "#/components/schemas/PersonEmailFindSummaryModel"
          },
          "phoneFind": {
            "$ref": "#/components/schemas/PersonPhoneFindSummaryModel"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PersonAccountModel"
            },
            "nullable": true
          },
          "tagIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "connectedVia": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ConnectedViaModel"
            },
            "nullable": true
          },
          "connectionIcpScore": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "importOnlyAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "emailDropped": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonPhoneFindSummaryModel": {
        "required": [
          "status"
        ],
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "requestedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "PersonPhoneModel": {
        "required": [
          "kind",
          "number",
          "source"
        ],
        "type": "object",
        "properties": {
          "number": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "source": {
            "type": "string",
            "nullable": true
          },
          "addedAt": {
            "type": "string",
            "format": "date-time"
          },
          "invalidAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonProfileCertification": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "issuer": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonProfileCompany": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "domain": {
            "type": "string",
            "nullable": true
          },
          "linkedinUrl": {
            "type": "string",
            "nullable": true
          },
          "kenCompanyId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonProfileEducation": {
        "type": "object",
        "properties": {
          "school": {
            "type": "string",
            "nullable": true
          },
          "degree": {
            "type": "string",
            "nullable": true
          },
          "fieldOfStudy": {
            "type": "string",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "nullable": true
          },
          "endedAt": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonProfileModel": {
        "type": "object",
        "properties": {
          "summary": {
            "type": "string",
            "nullable": true
          },
          "industry": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "currentCompany": {
            "$ref": "#/components/schemas/PersonProfileCompany"
          },
          "yearsOfExperience": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "yearsInCurrentRole": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "yearsInCurrentCompany": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "connectionsCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "followerCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "experience": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PersonProfileRole"
            },
            "nullable": true
          },
          "education": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PersonProfileEducation"
            },
            "nullable": true
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "certifications": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PersonProfileCertification"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonProfileRole": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "nullable": true
          },
          "endedAt": {
            "type": "string",
            "nullable": true
          },
          "isCurrent": {
            "type": "boolean",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PersonSourceModel": {
        "required": [
          "source"
        ],
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PhoneNumberValidityEnum": {
        "enum": [
          "unknown",
          "invalid",
          "risky",
          "verified",
          "valid"
        ],
        "type": "string"
      },
      "PlacementCountsModel": {
        "type": "object",
        "properties": {
          "inbox": {
            "type": "integer",
            "format": "int32"
          },
          "promotions": {
            "type": "integer",
            "format": "int32"
          },
          "other": {
            "type": "integer",
            "format": "int32"
          },
          "spam": {
            "type": "integer",
            "format": "int32"
          },
          "missing": {
            "type": "integer",
            "format": "int32"
          },
          "total": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Seed copies per placement. `total` is their sum."
      },
      "PlacementProviderBreakdown": {
        "type": "object",
        "properties": {
          "googleWorkspace": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "googlePersonal": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "outlookWorkspace": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "outlookPersonal": {
            "type": "number",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Inbox share for one stored provider bucket. Values are fractions from 0 to 1.\nA property is omitted when that provider was not in the stored JSON."
      },
      "PlacementProviderResultModel": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "nullable": true
          },
          "inbox": {
            "type": "integer",
            "format": "int32"
          },
          "promotions": {
            "type": "integer",
            "format": "int32"
          },
          "other": {
            "type": "integer",
            "format": "int32"
          },
          "spam": {
            "type": "integer",
            "format": "int32"
          },
          "missing": {
            "type": "integer",
            "format": "int32"
          },
          "total": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "PlacementSeedResultModel": {
        "type": "object",
        "properties": {
          "seed": {
            "type": "string",
            "description": "Masked seed address, such as `d***@gmail.com`.",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "senderEmail": {
            "type": "string",
            "nullable": true
          },
          "placement": {
            "type": "string",
            "description": "`inbox`, `promotions`, `other`, `spam` or `missing`.",
            "nullable": true
          },
          "folder": {
            "type": "string",
            "description": "The Gmail label or Outlook folder, such as `SPAM` or `Junk Email`.",
            "nullable": true
          },
          "detectedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PlacementSenderResultModel": {
        "type": "object",
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          },
          "inbox": {
            "type": "integer",
            "format": "int32"
          },
          "promotions": {
            "type": "integer",
            "format": "int32"
          },
          "other": {
            "type": "integer",
            "format": "int32"
          },
          "spam": {
            "type": "integer",
            "format": "int32"
          },
          "missing": {
            "type": "integer",
            "format": "int32"
          },
          "total": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "PlacementTestErrorModel": {
        "type": "object",
        "properties": {
          "message": {
            "type": "string",
            "nullable": true
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PlacementTestModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "sequenceId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "sequenceVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "inboxRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "spamRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "categoryRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "missingRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "code": {
            "type": "string",
            "nullable": true
          },
          "openPixelHost": {
            "type": "string",
            "description": "Host of the campaign open pixel the test sent (`openPixel: true` on create, DEV-5587). Set on create and on\n`GET /v1/placement-tests/{placementTestId}`; omitted when the test carries no pixel.",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "description": "Stored vendor name, such as `plusvibe`. Omitted when the row has none.",
            "nullable": true
          },
          "dataPoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlacementProviderBreakdown"
            },
            "description": "One breakdown derived from stored InboxKit `byProvider` folder counts.\nOmitted when no stored provider maps to a screen bucket.",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "type": {
            "type": "string",
            "description": "`weekly`, `on_demand` or `pre_launch`.",
            "nullable": true
          },
          "startedAt": {
            "type": "string",
            "description": "When InboxKit started sending the test.",
            "format": "date-time",
            "nullable": true
          },
          "sentCount": {
            "type": "integer",
            "description": "Emails InboxKit sent. 0 when it sent nothing, for example because it refused every sender\n(see Ken.Scraper.API.Canonical.PlacementTestModel.Errors).",
            "format": "int32",
            "nullable": true
          },
          "failureReason": {
            "type": "string",
            "nullable": true
          },
          "senderInboxIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "The inboxes the test sent from.",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "description": "The subject sent, with the sample lead's variables filled. Omitted for tests created before it was stored.",
            "nullable": true
          },
          "body": {
            "type": "string",
            "description": "The body sent, filled like Ken.Scraper.API.Canonical.PlacementTestModel.Subject.",
            "nullable": true
          },
          "counts": {
            "$ref": "#/components/schemas/PlacementCountsModel"
          },
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlacementProviderResultModel"
            },
            "description": "Per seed provider: `gmail`, `google_workspace`, `outlook`, `microsoft_365`.",
            "nullable": true
          },
          "senders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlacementSenderResultModel"
            },
            "description": "Per sending mailbox, including one whose mail reached no seed.",
            "nullable": true
          },
          "seeds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlacementSeedResultModel"
            },
            "description": "One row per seed and sender. Seed addresses are masked.",
            "nullable": true
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlacementTestErrorModel"
            },
            "description": "Errors InboxKit reported, such as a sender it does not support.",
            "nullable": true
          },
          "earlierTests": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PlacementTestTrendModel"
            },
            "description": "Up to 10 earlier tests of this test's own campaign and domain (whichever are set), newest first. A weekly test\nshared to another campaign's list still trends with the campaign that owns it; an inbox test without a domain\nhas none.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PlacementTestTrendModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "domainId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "inboxRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "spamRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "categoryRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "missingRate": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "An earlier test on the detail's trend. Rates are fractions from 0 to 1."
      },
      "PreviewSearchImportRequest": {
        "type": "object",
        "properties": {
          "personIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Search person ids the import would take.",
            "nullable": true
          },
          "searchFilters": {
            "description": "A people search body, as sent to `POST /v1/search/imports`. Previews its matches up to `limit`.",
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "description": "Most people a `searchFilters` import would add (5,000 when absent).",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body for `POST /v1/search/imports/preview`: the selection an import would send, without the campaign. Send\nexactly one of `personIds` and `searchFilters`."
      },
      "PreviewTriggerRequest": {
        "type": "object",
        "properties": {
          "signalType": {
            "type": "string",
            "description": "The signal to preview, snake_case: `fundraising`, `open_roles` or `company_headcount_growth`.",
            "nullable": true
          },
          "parameters": {
            "description": "The definition parameters as a JSON object, the same keys a trigger stores."
          },
          "limit": {
            "type": "integer",
            "description": "Companies per page, 1 to 25. Default 25.",
            "format": "int32",
            "nullable": true
          },
          "cursor": {
            "type": "string",
            "description": "Opaque cursor from `pagination.nextCursor` of the previous page.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/triggers/preview`."
      },
      "ProblemDetails": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "detail": {
            "type": "string",
            "nullable": true
          },
          "instance": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": { }
      },
      "PromptModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "prompt": {
            "type": "string",
            "nullable": true
          },
          "audienceDescription": {
            "type": "string",
            "nullable": true
          },
          "qualificationCriteria": {
            "type": "string",
            "nullable": true
          },
          "disqualificationCriteria": {
            "type": "string",
            "nullable": true
          },
          "scoringCriteria": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "flow": {
            "type": "string",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "segmentName": {
            "type": "string",
            "nullable": true
          },
          "promptTemplateId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "toOutput": {
            "type": "boolean"
          },
          "toRewrite": {
            "type": "integer",
            "format": "int32"
          },
          "order": {
            "type": "integer",
            "format": "int32"
          },
          "fallbackIfEmpty": {
            "type": "string",
            "nullable": true
          },
          "isRequiredForSending": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "PromptTestOutputModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PromptTestOverrideRequest": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "nullable": true
          },
          "maxTokens": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "temperature": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "reasoningLevel": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PromptTestResultModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "flow": {
            "type": "string",
            "nullable": true
          },
          "requestedSampleSize": {
            "type": "integer",
            "format": "int32"
          },
          "returnedSampleSize": {
            "type": "integer",
            "format": "int32"
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "cacheStrategy": {
            "type": "string",
            "nullable": true
          },
          "successCount": {
            "type": "integer",
            "format": "int32"
          },
          "failureCount": {
            "type": "integer",
            "format": "int32"
          },
          "usageSummary": {
            "$ref": "#/components/schemas/PromptTestUsageModel"
          },
          "samples": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptTestSampleModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PromptTestSampleModel": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "integer",
            "format": "int64"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "segmentName": {
            "type": "string",
            "nullable": true
          },
          "success": {
            "type": "boolean"
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "cacheStrategy": {
            "type": "string",
            "nullable": true
          },
          "rewritingProvider": {
            "type": "string",
            "nullable": true
          },
          "rewritingModel": {
            "type": "string",
            "nullable": true
          },
          "rewritingCacheStrategy": {
            "type": "string",
            "nullable": true
          },
          "usage": {
            "$ref": "#/components/schemas/PromptTestTokenUsageModel"
          },
          "estimatedCostUsd": {
            "type": "number",
            "format": "double"
          },
          "errorMessage": {
            "type": "string",
            "nullable": true
          },
          "isQualified": {
            "type": "boolean",
            "nullable": true
          },
          "qualificationResponse": {
            "type": "string",
            "nullable": true
          },
          "matchedSegmentName": {
            "type": "string",
            "nullable": true
          },
          "segmentationReasoning": {
            "type": "string",
            "nullable": true
          },
          "personalizationOutputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptTestOutputModel"
            },
            "nullable": true
          },
          "rewritingOutputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptTestOutputModel"
            },
            "nullable": true
          },
          "finalOutputs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptTestOutputModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PromptTestTokenUsageModel": {
        "type": "object",
        "properties": {
          "inputTokens": {
            "type": "integer",
            "format": "int32"
          },
          "outputTokens": {
            "type": "integer",
            "format": "int32"
          },
          "totalTokens": {
            "type": "integer",
            "format": "int32"
          },
          "cacheCreationTokens": {
            "type": "integer",
            "format": "int32"
          },
          "cacheReadTokens": {
            "type": "integer",
            "format": "int32"
          },
          "reasoningTokens": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "PromptTestUsageModel": {
        "type": "object",
        "properties": {
          "averageInputTokens": {
            "type": "integer",
            "format": "int32"
          },
          "averageCacheReadTokens": {
            "type": "integer",
            "format": "int32"
          },
          "averageOutputTokens": {
            "type": "integer",
            "format": "int32"
          },
          "totalEstimatedCostUsd": {
            "type": "number",
            "format": "double"
          },
          "averageEstimatedCostUsd": {
            "type": "number",
            "format": "double"
          }
        },
        "additionalProperties": false
      },
      "PromptVersionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "segmentId": {
            "type": "integer",
            "format": "int64"
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByEmail": {
            "type": "string",
            "nullable": true
          },
          "isRevert": {
            "type": "boolean"
          },
          "restoredFromVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "restoredFromVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "restoredFromCreatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "prompts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PromptVersionPromptModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "PromptVersionPromptModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "prompt": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "flow": {
            "type": "string",
            "nullable": true
          },
          "order": {
            "type": "integer",
            "format": "int32"
          },
          "toOutput": {
            "type": "boolean"
          },
          "toRewrite": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "PromptVersionRestoreModel": {
        "type": "object",
        "properties": {
          "dryRun": {
            "type": "boolean",
            "description": "True when the request was a dry run: nothing was restored and Ken.Scraper.API.Canonical.PromptVersionRestoreModel.Impact is the preview."
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "versionWarning": {
            "type": "string",
            "description": "Set when the restore applied but version history or the model configuration was not fully captured.",
            "nullable": true
          },
          "hasImpact": {
            "type": "boolean",
            "description": "Dry run only: whether the restore would clear campaign AI output.",
            "nullable": true
          },
          "impact": {
            "$ref": "#/components/schemas/CanonicalInvalidationImpact"
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RecipientProviderCountModel": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "`mailbox_provider` or `security_gateway`.",
            "nullable": true
          },
          "leadCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "RecipientProviderCountsModel": {
        "type": "object",
        "properties": {
          "providers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RecipientProviderCountModel"
            },
            "description": "Every active mailbox provider and security gateway, 0 included, most leads first. A lead counts once under its\nmailbox provider and once under its security gateway.",
            "nullable": true
          },
          "pendingCount": {
            "type": "integer",
            "description": "Leads whose provider is still being detected.",
            "format": "int32"
          },
          "noProviderCount": {
            "type": "integer",
            "description": "Leads whose domain has no listed provider (self-hosted mail, no MX, an unknown host).",
            "format": "int32"
          },
          "isPartial": {
            "type": "boolean",
            "description": "True when the campaign has more than 100,000 leads that can still get an email; counts cover the first 100,000 by id."
          }
        },
        "additionalProperties": false,
        "description": "DEV-5225: the campaign's leads behind each active mailbox provider and security gateway."
      },
      "RecipientProviderModel": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string",
            "description": "Stable key, such as `google_workspace`, `microsoft_365` or `mimecast`.",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "`mailbox_provider` or `security_gateway`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A mailbox provider or security gateway from the provider catalog."
      },
      "RecoverWebhookDeliveriesRequest": {
        "type": "object",
        "properties": {
          "since": {
            "type": "string",
            "description": "Required. Start of the window (ISO 8601, UTC), at most 14 days ago.",
            "format": "date-time",
            "nullable": true
          },
          "until": {
            "type": "string",
            "description": "End of the window (ISO 8601, UTC). Default: now.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RefreshOutboundSiteRequest": {
        "type": "object",
        "properties": {
          "note": {
            "type": "string",
            "description": "An instruction for the rebuild, such as \"drop the pricing section\". At most 1000 characters.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "POST /v1/outbound-site/refresh (DEV-1095)."
      },
      "RefusalDto": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "metric": {
            "type": "string",
            "nullable": true
          },
          "used": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "remaining": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "planType": {
            "type": "string",
            "nullable": true
          },
          "remedy": {
            "type": "string",
            "nullable": true
          },
          "unlocksAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "requiredMillicredits": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "availableMillicredits": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "restrictedMillicredits": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RegenerateLocalizationRequest": {
        "type": "object",
        "properties": {
          "instruction": {
            "type": "string",
            "description": "What to change, in a sentence or two, such as `Shorter, and less formal.` Up to 2,000 characters.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of POST /v1/campaigns/{campaignId}/localizations/{localizationId}/regenerate. Optional."
      },
      "RenameInboxRequest": {
        "type": "object",
        "properties": {
          "localPart": {
            "type": "string",
            "description": "The new username: the part before the `@` (`jane.doe`, not `jane.doe@acme.com`). The domain stays.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-15: body of `POST /v1/inboxes/{inboxId}/rename`."
      },
      "ReplaceCampaignAiWorkflowsRequest": {
        "type": "object",
        "properties": {
          "aiWorkflowIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "The full set of AI workflow ids to attach: 1 qualification, 2 personalization,\n3 rewriting, 4 segmentation, 6 scoring. An empty list detaches every workflow.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceCampaignInboxesRequest": {
        "type": "object",
        "properties": {
          "inboxIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "assignAllActive": {
            "type": "boolean"
          },
          "provider": {
            "type": "string",
            "nullable": true
          },
          "allInboxes": {
            "type": "boolean",
            "description": "True turns on live \"All inboxes\": every inbox a launch would assign joins now, inboxes connected later join too,\nand `inboxIds`, `assignAllActive` and `provider` are ignored. Needs the workspace's\n`sender_routing` flag, else `400 validation_failed` with detail code `feature_disabled`. Absent or\nfalse keeps a saved list: any save without it fixes the pool to the inboxes sent.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceCampaignLinkedInAccountsRequest": {
        "type": "object",
        "properties": {
          "linkedInAccountIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "assignAllConnected": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "ReplaceCampaignSenderRouteRule": {
        "type": "object",
        "properties": {
          "provider": {
            "type": "string",
            "description": "An active mailbox provider or security gateway slug, such as `google_workspace` or `mimecast`.",
            "nullable": true
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Whole sending domains (the part after `@` of a workspace inbox); inboxes added on them later join the rule. Lowercased when saved.",
            "nullable": true
          },
          "inboxIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Single workspace inbox ids.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "One rule: prospects on Ken.Scraper.API.Dtos.ReplaceCampaignSenderRouteRule.Provider get their first email only from these domains and inboxes."
      },
      "ReplaceCampaignSenderRoutingRequest": {
        "type": "object",
        "properties": {
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplaceCampaignSenderRouteRule"
            },
            "description": "At most one rule per provider. Required.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-5225: the full set of a campaign's sender rules. `[]` clears them."
      },
      "ReplaceCrmFieldMappingsBody": {
        "type": "object",
        "properties": {
          "objectType": {
            "type": "string",
            "nullable": true
          },
          "mappings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmFieldMappingBody"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceEmailSequenceRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplaceEmailSequenceStepRequest"
            },
            "nullable": true
          },
          "expectedModifiedAt": {
            "type": "string",
            "description": "Optional. The `modifiedAt` from your last read. When the live sequence changed since, the replace is refused\nwith 409 `conflict` and detail code `stale_write`, so you do not overwrite someone else's edit.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceEmailSequenceStepRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "bodyFormat": {
            "type": "string",
            "nullable": true
          },
          "waitDays": {
            "type": "integer",
            "format": "int32"
          },
          "isActive": {
            "type": "boolean"
          },
          "openTrackingEnabled": {
            "type": "boolean"
          },
          "handwrittenEnabled": {
            "type": "boolean",
            "description": "DEV-2729: send the letter part of the body as a handwritten letter image. A replace without it turns the\nletter off, like openTrackingEnabled."
          },
          "handwrittenBackground": {
            "type": "string",
            "description": "The letter paper: walnut, linen, kraft, marble, deckle or notepad; null is walnut.",
            "nullable": true
          },
          "handwrittenIntro": {
            "type": "string",
            "description": "The normal-text line above the letter, at most 200 characters on one line; null is the default.",
            "nullable": true
          },
          "studioTemplateVersionId": {
            "type": "integer",
            "description": "DEV-3559: a published Studio email version this step sends. The step becomes html with the version's fallback as\nbody and subject, so body, subject and bodyFormat sent with a pin are ignored. Null or omitted unpins. Needs the\nstudio, studio_email and html_steps flags. Only the sequence replace reads it: a saved version\n(POST .../email-sequence/versions) ignores it and keeps the body and subject sent, so restoring that version\nunpins the step.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceLinkedInSequenceRequest": {
        "type": "object",
        "properties": {
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplaceLinkedInSequenceStepRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceLinkedInSequenceStepRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "stepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "stepType": {
            "type": "string",
            "nullable": true
          },
          "variant": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "waitDays": {
            "type": "integer",
            "format": "int32"
          },
          "anchorEmailStepOrder": {
            "type": "integer",
            "format": "int32"
          },
          "positionInGap": {
            "type": "integer",
            "format": "int32"
          },
          "conditionType": {
            "type": "string",
            "nullable": true
          },
          "conditionScopeStepOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isOptional": {
            "type": "boolean"
          },
          "openProfileOnly": {
            "type": "boolean"
          },
          "isActive": {
            "type": "boolean"
          },
          "noteMode": {
            "type": "string",
            "description": "template or ai. Omitted keeps the stored value (template for a new row).",
            "nullable": true
          },
          "aiInstructions": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceLinkedInSettingsRequest": {
        "type": "object",
        "properties": {
          "isEnabled": {
            "type": "boolean"
          },
          "channelPolicy": {
            "type": "string",
            "nullable": true
          },
          "notAcceptedAfterDays": {
            "type": "integer",
            "format": "int32"
          },
          "conditionWaitDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "isWithdrawEnabled": {
            "type": "boolean"
          },
          "stopLinkedInOnEmailReply": {
            "type": "boolean"
          },
          "stopEmailOnLinkedInReply": {
            "type": "boolean"
          },
          "stopSequenceForCompanyOnReply": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplaceScoringSettingsRequest": {
        "type": "object",
        "properties": {
          "isEnabled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "ReplyClassificationCountModel": {
        "type": "object",
        "properties": {
          "classification": {
            "type": "string",
            "nullable": true
          },
          "count": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "ReplyClassificationGroupModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "configurationId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "interestedCount": {
            "type": "integer",
            "format": "int32"
          },
          "counts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplyClassificationCountModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplyClassificationsModel": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "totalCount": {
            "type": "integer",
            "format": "int32"
          },
          "interestedCount": {
            "type": "integer",
            "format": "int32"
          },
          "counts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplyClassificationCountModel"
            },
            "nullable": true
          },
          "byCampaign": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplyClassificationGroupModel"
            },
            "nullable": true
          },
          "bySegment": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplyClassificationGroupModel"
            },
            "nullable": true
          },
          "byConfiguration": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplyClassificationGroupModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ReplyTemplateModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "authorSource": {
            "type": "string",
            "nullable": true
          },
          "scope": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ResetAiRunContactsRequest": {
        "type": "object",
        "properties": {
          "flow": {
            "type": "string",
            "description": "personalization or rewriting.",
            "nullable": true
          },
          "contactIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "1 to 500 contact ids of the campaign.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-3008: reset chosen contacts of a campaign. Its own route, so a build without it\nanswers 404 instead of reading the body as a campaign-wide reset."
      },
      "ResetAiRunRequest": {
        "type": "object",
        "properties": {
          "flow": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RestorePromptVersionRequest": {
        "type": "object",
        "properties": {
          "confirm": {
            "type": "boolean"
          },
          "dryRun": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "RestoreSegmentVersionRequest": {
        "type": "object",
        "properties": {
          "confirm": {
            "type": "boolean"
          },
          "dryRun": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "RetryEnrichmentModel": {
        "type": "object",
        "properties": {
          "companyStatusesCleared": {
            "type": "integer",
            "format": "int32"
          },
          "scrapeFailuresCleared": {
            "type": "integer",
            "format": "int32"
          },
          "contactStatusesCleared": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "RunCampaignScoringRequest": {
        "type": "object",
        "properties": {
          "contactIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RunwayAutopilotModel": {
        "type": "object",
        "properties": {
          "on": {
            "type": "boolean"
          },
          "audienceApproved": {
            "type": "boolean",
            "description": "The campaign has an approved audience for lead top-ups."
          },
          "weeklyTopUpLimit": {
            "type": "integer",
            "format": "int32"
          },
          "toppedUpLast7Days": {
            "type": "integer",
            "description": "Leads the team added over the last 7 days.",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "RunwayCampaignModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "sendingStatus": {
            "type": "string",
            "description": "`not_started`, `scheduled`, `sending`, `paused`, `completed`, `error`, `launching` or `archived`.",
            "nullable": true
          },
          "autopilot": {
            "$ref": "#/components/schemas/RunwayAutopilotModel"
          },
          "leads": {
            "$ref": "#/components/schemas/RunwayLeadsModel"
          },
          "capacity": {
            "$ref": "#/components/schemas/RunwayCapacityModel"
          },
          "inboxes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunwayInboxModel"
            },
            "nullable": true
          },
          "placement": {
            "$ref": "#/components/schemas/RunwayPlacementModel"
          },
          "replies": {
            "$ref": "#/components/schemas/RunwayRepliesModel"
          }
        },
        "additionalProperties": false
      },
      "RunwayCapacityModel": {
        "type": "object",
        "properties": {
          "dailyCap": {
            "type": "integer",
            "description": "The campaign's daily cap, or the inbox capacity when the campaign has none.",
            "format": "int32"
          },
          "rampFloor": {
            "type": "integer",
            "description": "The ramped cap while the campaign's ramp runs; omitted otherwise.",
            "format": "int32",
            "nullable": true
          },
          "inboxCapacity": {
            "type": "integer",
            "description": "The sum of the campaign's inbox daily limits.",
            "format": "int32"
          },
          "healthyInboxCapacity": {
            "type": "integer",
            "description": "The same without the sick inboxes.",
            "format": "int32"
          },
          "short": {
            "type": "boolean",
            "description": "The healthy inboxes cannot send the daily cap."
          }
        },
        "additionalProperties": false
      },
      "RunwayInboxModel": {
        "type": "object",
        "properties": {
          "inboxId": {
            "type": "integer",
            "format": "int64"
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "dailyLimit": {
            "type": "integer",
            "format": "int32"
          },
          "sends7d": {
            "type": "integer",
            "description": "Sends over the last 7 days.",
            "format": "int64"
          },
          "bounceRate7d": {
            "type": "number",
            "description": "Bounces over sends in the last 7 days, a fraction 0-1.",
            "format": "double"
          },
          "sick": {
            "type": "boolean"
          },
          "sickReason": {
            "type": "string",
            "description": "`not_active` (the inbox is not active), `paused` (a member paused it), `auto_paused` (a Ken send\n            block holds it), `bounces` or `domain_health`, the first that holds; omitted when the inbox is healthy.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RunwayLeadsModel": {
        "type": "object",
        "properties": {
          "notStarted": {
            "type": "integer",
            "description": "Ready leads still waiting for their first email.",
            "format": "int32"
          },
          "firstTouchesPerDay": {
            "type": "number",
            "description": "First emails a day over the last 7 days, one decimal.",
            "format": "double"
          },
          "runwayDays": {
            "type": "integer",
            "description": "Days the not-started leads last at that rate, rounded down; omitted when no first email went out.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RunwayModel": {
        "type": "object",
        "properties": {
          "workspace": {
            "$ref": "#/components/schemas/RunwayWorkspaceModel"
          },
          "campaigns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RunwayCampaignModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The lead runway and sending health of the workspace's live campaigns (DEV-3671)."
      },
      "RunwayPlacementModel": {
        "type": "object",
        "properties": {
          "completedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "inboxRate": {
            "type": "number",
            "description": "Share of seed inboxes that got the email in the inbox, 0-1.",
            "format": "double",
            "nullable": true
          },
          "spamRate": {
            "type": "number",
            "description": "Share that got it in spam, 0-1.",
            "format": "double",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "RunwayRepliesModel": {
        "type": "object",
        "properties": {
          "interested7d": {
            "type": "integer",
            "description": "Distinct leads who replied Interested by email over the last 7 days.",
            "format": "int32"
          },
          "unansweredInterested": {
            "type": "integer",
            "description": "Interested email threads not answered since the lead last wrote and not archived. A due reminder does not count\na thread here, unlike the To Reply tab.",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "RunwayWorkspaceModel": {
        "type": "object",
        "properties": {
          "targetInterestedPerWeek": {
            "type": "integer",
            "description": "Interested replies a week the workspace aims for; omitted when none is set.",
            "format": "int32",
            "nullable": true
          },
          "runwayDays": {
            "type": "integer",
            "description": "Days of leads to keep ready on each campaign.",
            "format": "int32"
          },
          "clientWorkspace": {
            "type": "boolean",
            "description": "A client workspace; omitted while staff have not decided.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SaveEmailSequenceVersionRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean",
            "nullable": true
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplaceEmailSequenceStepRequest"
            },
            "nullable": true
          },
          "sourceVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SaveLinkedInVersionRequest": {
        "type": "object",
        "properties": {
          "sourceVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ReplaceLinkedInSequenceStepRequest"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SaveSegmentVersionRequest": {
        "type": "object",
        "properties": {
          "sourceVersionId": {
            "type": "integer",
            "description": "The version to build on. Omit it to build on the live segment.",
            "format": "int64",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "segmentationType": {
            "type": "string",
            "description": "`manual`, `ai` or `ab_test`.",
            "nullable": true
          },
          "abTestPercentage": {
            "type": "integer",
            "description": "0 to 100.",
            "format": "int32",
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "filterCriteria": {
            "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaDTO"
          }
        },
        "additionalProperties": false,
        "description": "DEV-15: body of `POST /v1/segments/{segmentId}/versions`: the `PATCH /v1/segments/{segmentId}` fields\nplus `sourceVersionId`. Absent fields keep the live segment's value, or the `sourceVersionId` version's\nvalue when one is given; JSON null clears `description` and `abTestPercentage`, as on PATCH."
      },
      "SavedListAccessEnum": {
        "enum": [
          "owner",
          "shared",
          "library"
        ],
        "type": "string"
      },
      "SavedListCountsModel": {
        "type": "object",
        "properties": {
          "members": {
            "type": "integer",
            "format": "int32"
          },
          "sendableEmails": {
            "type": "integer",
            "format": "int32"
          },
          "byCountry": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "bySeniority": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "byIndustry": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "byHeadcountBand": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SavedListGrantModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "savedListId": {
            "type": "integer",
            "format": "int64"
          },
          "inviteeEmail": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/SavedListGrantStatusEnum"
          },
          "receivingWorkspaceId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "receivingWorkspaceName": {
            "type": "string",
            "nullable": true
          },
          "invitedByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "acceptedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "revokedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "SavedListGrantStatusEnum": {
        "enum": [
          "pending",
          "accepted",
          "revoked"
        ],
        "type": "string"
      },
      "SavedListInviteModel": {
        "type": "object",
        "properties": {
          "token": {
            "type": "string",
            "nullable": true
          },
          "listName": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "$ref": "#/components/schemas/SavedListKindEnum"
          },
          "memberCount": {
            "type": "integer",
            "format": "int32"
          },
          "ownerWorkspaceName": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "$ref": "#/components/schemas/SavedListGrantStatusEnum"
          }
        },
        "additionalProperties": false
      },
      "SavedListKindEnum": {
        "enum": [
          "people",
          "companies"
        ],
        "type": "string"
      },
      "SavedListLibraryStateEnum": {
        "enum": [
          "none",
          "submitted",
          "approved",
          "rejected",
          "retired"
        ],
        "type": "string"
      },
      "SavedListMemberFiltersBody": {
        "type": "object",
        "properties": {
          "country": {
            "type": "string",
            "nullable": true
          },
          "seniority": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "industry": {
            "type": "string",
            "nullable": true
          },
          "headcountBand": {
            "type": "string",
            "nullable": true
          },
          "hasSendableEmail": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SavedListMemberModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "identityKey": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "seniority": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "industry": {
            "type": "string",
            "nullable": true
          },
          "headcountBand": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "linkedinUrl": {
            "type": "string",
            "nullable": true
          },
          "hasSendableEmail": {
            "type": "boolean"
          },
          "emailCount": {
            "type": "integer",
            "format": "int32"
          },
          "phoneCount": {
            "type": "integer",
            "format": "int32"
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "custom": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SavedListModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "$ref": "#/components/schemas/SavedListKindEnum"
          },
          "visibility": {
            "$ref": "#/components/schemas/SavedListVisibilityEnum"
          },
          "access": {
            "$ref": "#/components/schemas/SavedListAccessEnum"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "icpTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "libraryState": {
            "$ref": "#/components/schemas/SavedListLibraryStateEnum"
          },
          "publicPageEnabled": {
            "type": "boolean"
          },
          "ownerUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "rightsConfirmedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "hasCsvMembers": {
            "type": "boolean"
          },
          "counts": {
            "$ref": "#/components/schemas/SavedListCountsModel"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedListSourceModel"
            },
            "nullable": true
          },
          "lastRefreshedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewReason": {
            "type": "string",
            "nullable": true
          },
          "submittedByWorkspaceName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "SavedListRightsCountsModel": {
        "type": "object",
        "properties": {
          "members": {
            "type": "integer",
            "format": "int32"
          },
          "sendableEmails": {
            "type": "integer",
            "format": "int32"
          },
          "byCountry": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "bySeniority": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "byIndustry": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "byHeadcountBand": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SavedListRightsModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "$ref": "#/components/schemas/SavedListKindEnum"
          },
          "visibility": {
            "$ref": "#/components/schemas/SavedListVisibilityEnum"
          },
          "access": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "icpTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "libraryState": {
            "$ref": "#/components/schemas/SavedListLibraryStateEnum"
          },
          "publicPageEnabled": {
            "type": "boolean"
          },
          "ownerUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "rightsConfirmedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "hasCsvMembers": {
            "type": "boolean"
          },
          "counts": {
            "$ref": "#/components/schemas/SavedListRightsCountsModel"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedListSourceModel"
            },
            "nullable": true
          },
          "lastRefreshedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewReason": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "SavedListSourceModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "sourceType": {
            "$ref": "#/components/schemas/SavedListSourceTypeEnum"
          },
          "parameters": { },
          "status": {
            "$ref": "#/components/schemas/SavedListSourceStatusEnum"
          },
          "statusMessage": {
            "type": "string",
            "nullable": true
          },
          "addedByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "lastRefreshedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastRefreshAdded": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "SavedListSourceStatusEnum": {
        "enum": [
          "pending",
          "running",
          "done",
          "failed"
        ],
        "type": "string"
      },
      "SavedListSourceTypeEnum": {
        "enum": [
          "search_filters",
          "search_selection",
          "saved_search",
          "csv",
          "campaign",
          "list",
          "vendor_import",
          "registry",
          "job_posts"
        ],
        "type": "string"
      },
      "SavedListSubmissionCountsModel": {
        "type": "object",
        "properties": {
          "members": {
            "type": "integer",
            "format": "int32"
          },
          "sendableEmails": {
            "type": "integer",
            "format": "int32"
          },
          "byCountry": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "bySeniority": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "byIndustry": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "byHeadcountBand": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SavedListSubmissionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "$ref": "#/components/schemas/SavedListKindEnum"
          },
          "visibility": {
            "$ref": "#/components/schemas/SavedListVisibilityEnum"
          },
          "access": {
            "type": "string",
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "icpTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "libraryState": {
            "$ref": "#/components/schemas/SavedListLibraryStateEnum"
          },
          "publicPageEnabled": {
            "type": "boolean"
          },
          "ownerUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "rightsConfirmedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "hasCsvMembers": {
            "type": "boolean"
          },
          "counts": {
            "$ref": "#/components/schemas/SavedListSubmissionCountsModel"
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SavedListSourceModel"
            },
            "nullable": true
          },
          "lastRefreshedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "reviewReason": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "SavedListVisibilityEnum": {
        "enum": [
          "private",
          "workspace",
          "library"
        ],
        "type": "string"
      },
      "ScheduledMessageDraftModel": {
        "type": "object",
        "properties": {
          "messageId": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "senderEmailId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "to": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "cc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "bcc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "saved": {
            "type": "boolean",
            "description": "False when the cancel went through but saving this draft back as the thread's draft failed (DEV-6494).\nThe caller still has the draft here and saves it itself."
          }
        },
        "additionalProperties": false
      },
      "ScheduledMessageModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "messageId": {
            "type": "string",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "scheduled, sending, sent, cancelled, failed, or awaiting_approval (DEV-2043).",
            "nullable": true
          },
          "approverMemberId": {
            "type": "integer",
            "description": "With status awaiting_approval: the client seat whose own inbox sends the reply and who must approve it\n(DEV-2043). Names come from `/v1/members`.",
            "format": "int64",
            "nullable": true
          },
          "delaySeconds": {
            "type": "integer",
            "format": "int32"
          },
          "sendAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "senderEmailId": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "to": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "cc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "bcc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "draft": {
            "$ref": "#/components/schemas/ScheduledMessageDraftModel"
          }
        },
        "additionalProperties": false
      },
      "ScoringSettingsModel": {
        "type": "object",
        "properties": {
          "isEnabled": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "SearchContactDTO": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "headline": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "companyDomain": {
            "type": "string",
            "nullable": true
          },
          "companyLinkedInUrl": {
            "type": "string",
            "nullable": true
          },
          "companyIndustry": {
            "type": "string",
            "nullable": true
          },
          "companyEmployeeCount": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyDescription": {
            "type": "string",
            "nullable": true
          },
          "companyType": {
            "type": "string",
            "nullable": true
          },
          "companyFoundedYear": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyLocation": {
            "type": "string",
            "nullable": true
          },
          "companySpecialties": {
            "type": "string",
            "nullable": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          },
          "experiencesJson": {
            "type": "string",
            "nullable": true
          },
          "educationJson": {
            "type": "string",
            "nullable": true
          },
          "certificationsJson": {
            "type": "string",
            "nullable": true
          },
          "inferredSkills": {
            "type": "string",
            "nullable": true
          },
          "languages": {
            "type": "string",
            "nullable": true
          },
          "lastJobDescription": {
            "type": "string",
            "nullable": true
          },
          "kenCompanyId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "profilePhotoUrl": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true
          },
          "countryIso2": {
            "type": "string",
            "nullable": true
          },
          "seniorityLevel": {
            "type": "string",
            "nullable": true
          },
          "function": {
            "type": "string",
            "nullable": true
          },
          "isDecisionMaker": {
            "type": "boolean"
          },
          "yearsOfExperience": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "yearsInCurrentRole": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "yearsInCurrentCompany": {
            "type": "number",
            "format": "float",
            "nullable": true
          },
          "changedJobRecently": {
            "type": "boolean"
          },
          "jobChangeDate": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "companyFounded": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "headquartersCity": {
            "type": "string",
            "nullable": true
          },
          "headquartersState": {
            "type": "string",
            "nullable": true
          },
          "headquartersCountry": {
            "type": "string",
            "nullable": true
          },
          "companySize": {
            "type": "string",
            "nullable": true
          },
          "companyLogoUrl": {
            "type": "string",
            "nullable": true
          },
          "companyFollowers": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "companyTotalFunding": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "companyLastFundingRoundType": {
            "type": "string",
            "nullable": true
          },
          "companyLastFundingAmount": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "currentExperiences": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CurrentExperienceImportDTO"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SearchContactsRequest": {
        "type": "object",
        "properties": {
          "campaignIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "companyId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "q": {
            "type": "string",
            "nullable": true
          },
          "isQualified": {
            "type": "boolean",
            "nullable": true
          },
          "doNotContact": {
            "type": "boolean",
            "nullable": true
          },
          "createdAfter": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdBefore": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterGroup"
            },
            "nullable": true
          },
          "readyOnly": {
            "type": "boolean"
          },
          "contactIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          },
          "securityGateway": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-5062: contacts whose first Safe or Verified email sits behind one of these security gateways. Catalog slugs (for example\n`proofpoint`), `none` or `pending`; at most 100 values, OR'ed. Needs security gateways on the\nworkspace.",
            "nullable": true
          },
          "mailboxProvider": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-5062: contacts whose mailbox host is one of these. Catalog slugs (for example `google_workspace`),\n`unknown` or `pending`; at most 100 values, OR'ed. Needs security gateways on the workspace.",
            "nullable": true
          },
          "sort": {
            "type": "string",
            "description": "Allowlisted lead column. Same names as `POST /v1/leads`.",
            "nullable": true
          },
          "direction": {
            "type": "string",
            "description": "`asc` or `desc`. Empty means ascending.",
            "nullable": true
          },
          "limit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "cursor": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SearchImportPreview": {
        "type": "object",
        "properties": {
          "personCount": {
            "type": "integer",
            "description": "People the import would take: the distinct `personIds` (at most 5,000, the import's cap for picks), or the\nfilter's matches up to `limit` (5,000 when absent).",
            "format": "int64"
          },
          "checkedCount": {
            "type": "integer",
            "description": "People checked against Kenso's emails: the first 500 Search returned, in import order.",
            "format": "int32"
          },
          "kenEmailCount": {
            "type": "integer",
            "description": "Of the checked people, how many Kenso already holds a verified email for.",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "DEV-5490: what a Search import would take, and how many of those people Kenso already holds an email for. An\naddress Kenso already holds costs no email find on a paid plan. At most the first 500 people are checked, so\n`checkedCount` is below `personCount` for a larger selection (or when picked people are no longer in\nSearch). Search failing for any pick fails the preview (503), never a lower count."
      },
      "SearchListPagination": {
        "type": "object",
        "properties": {
          "nextCursor": {
            "type": "string",
            "nullable": true
          },
          "hasMore": {
            "type": "boolean"
          },
          "totalCount": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SearchListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": { },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/SearchListPagination"
          }
        },
        "additionalProperties": false,
        "description": "The Search list envelope. `totalCount` appears only when asked for with `includeTotal=true`."
      },
      "SearchSampleJobsTab": {
        "type": "object",
        "properties": {
          "request": { },
          "companies": { },
          "people": {
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SearchSampleQuery": {
        "type": "object",
        "properties": {
          "titles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "seniorityLevels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "industries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "headcountMin": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "headcountMax": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "countries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "hiringTitles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "fundingMinRaisedUsd": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "fundingRaisedWithinDays": {
            "type": "integer",
            "format": "int32"
          },
          "fundingIndustryGroups": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SearchSampleResource": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "refreshing": {
            "type": "boolean"
          },
          "generatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "query": {
            "$ref": "#/components/schemas/SearchSampleQuery"
          },
          "profiles": {
            "$ref": "#/components/schemas/SearchSampleTab"
          },
          "companies": {
            "$ref": "#/components/schemas/SearchSampleTab"
          },
          "jobs": {
            "$ref": "#/components/schemas/SearchSampleJobsTab"
          },
          "funding": {
            "$ref": "#/components/schemas/SearchSampleTab"
          }
        },
        "additionalProperties": false
      },
      "SearchSampleTab": {
        "type": "object",
        "properties": {
          "request": { },
          "page": { }
        },
        "additionalProperties": false
      },
      "SegmentFilterMetadataDTO": {
        "type": "object",
        "properties": {
          "seniorityLevels": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "functions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "industries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "companyTypes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "employmentTypes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "lastFundingRounds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "technologies": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "emailValidity": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "emailProviders": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          },
          "languages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FilterOptionItem"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SegmentModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isDefault": {
            "type": "boolean"
          },
          "isActive": {
            "type": "boolean"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "segmentationType": {
            "type": "string",
            "nullable": true
          },
          "abTestPercentage": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "contactCount": {
            "type": "integer",
            "description": "Omitted when the list was read with `includeMetrics=false`.",
            "format": "int32",
            "nullable": true
          },
          "rawContactCount": {
            "type": "integer",
            "description": "Omitted when the list was read with `includeMetrics=false`.",
            "format": "int32",
            "nullable": true
          },
          "readyContactCount": {
            "type": "integer",
            "description": "Omitted when the list was read with `includeMetrics=false`.",
            "format": "int32",
            "nullable": true
          },
          "filterCriteria": {
            "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaDTO"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 1207,
          "campaignId": 4821,
          "name": "Engineering leaders",
          "description": "VPs and heads of engineering at B2B SaaS companies with 50 to 500 employees.",
          "isDefault": false,
          "isActive": true,
          "sortOrder": 1,
          "segmentationType": "ai",
          "contactCount": 640,
          "rawContactCount": 712,
          "readyContactCount": 598,
          "createdAt": "2026-09-23T15:02:11Z",
          "modifiedAt": "2026-10-14T09:41:27Z"
        }
      },
      "SegmentPreviewContactModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "fullName": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "location": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "emailValidity": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SegmentPreviewModel": {
        "type": "object",
        "properties": {
          "matchingCount": {
            "type": "integer",
            "format": "int32"
          },
          "totalCampaignContacts": {
            "type": "integer",
            "format": "int32"
          },
          "sampleContacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SegmentPreviewContactModel"
            },
            "nullable": true
          },
          "filterOptions": {
            "$ref": "#/components/schemas/SegmentFilterMetadataDTO"
          }
        },
        "additionalProperties": false
      },
      "SegmentRestoreModel": {
        "type": "object",
        "properties": {
          "dryRun": {
            "type": "boolean"
          },
          "newVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "versionWarning": {
            "type": "string",
            "nullable": true
          },
          "version": {
            "$ref": "#/components/schemas/SegmentVersionModel"
          },
          "snapshot": {
            "$ref": "#/components/schemas/SegmentSnapshotModel"
          },
          "children": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SegmentVersionChildModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SegmentSnapshotHeaderModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "segmentationType": {
            "type": "string",
            "nullable": true
          },
          "abTestPercentage": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SegmentSnapshotModel": {
        "type": "object",
        "properties": {
          "schemaVersion": {
            "type": "integer",
            "format": "int32"
          },
          "segment": {
            "$ref": "#/components/schemas/SegmentSnapshotHeaderModel"
          },
          "filterCriteria": {
            "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaSnapshot"
          }
        },
        "additionalProperties": false
      },
      "SegmentVersionChildModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "parentId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "versionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "newVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "versionWarning": {
            "type": "string",
            "nullable": true
          },
          "snapshot": {
            "description": "Child snapshot from a dry-run preview (email steps, prompts, or LinkedIn steps).\nAbsent on an applied restore, which reports only the cascade outcome.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SegmentVersionDetailModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByEmail": {
            "type": "string",
            "nullable": true
          },
          "isRevert": {
            "type": "boolean"
          },
          "revertedFromVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "revertedFromVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "revertedFromCreatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "snapshot": {
            "$ref": "#/components/schemas/SegmentSnapshotModel"
          }
        },
        "additionalProperties": false
      },
      "SegmentVersionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByEmail": {
            "type": "string",
            "nullable": true
          },
          "isRevert": {
            "type": "boolean"
          },
          "revertedFromVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "revertedFromVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "revertedFromCreatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SegmentVersionSaveModel": {
        "type": "object",
        "properties": {
          "segment": {
            "$ref": "#/components/schemas/SegmentModel"
          },
          "version": {
            "$ref": "#/components/schemas/SegmentVersionModel"
          },
          "versionWarning": {
            "type": "string",
            "description": "Set when the save landed but version history was not captured.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-15: the result of `segments.save-version`: the saved segment and the version row written."
      },
      "SendWebhookEndpointTestRequest": {
        "type": "object",
        "properties": {
          "eventType": {
            "type": "string",
            "description": "Event type to send: any type available to the workspace, whether or not the endpoint receives it. Default: the first\nevent the endpoint receives (reply.received for every event).",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SenderRouteGroupModel": {
        "type": "object",
        "properties": {
          "sendableInboxCount": {
            "type": "integer",
            "format": "int32"
          },
          "dailyCapacity": {
            "type": "integer",
            "format": "int32"
          },
          "leadCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "SenderRouteRuleModel": {
        "type": "object",
        "properties": {
          "provider": {
            "$ref": "#/components/schemas/RecipientProviderModel"
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Whole sending domains, lowercased: an inbox added on one later joins the rule.",
            "nullable": true
          },
          "inboxIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Single inboxes.",
            "nullable": true
          },
          "sendableInboxCount": {
            "type": "integer",
            "description": "The campaign's inboxes the rule covers that can send now (Kenso-sendable, not paused).",
            "format": "int32"
          },
          "dailyCapacity": {
            "type": "integer",
            "description": "The summed daily send limits of those inboxes, in emails per day (an inbox with no limit set counts 0).",
            "format": "int32"
          },
          "leadCount": {
            "type": "integer",
            "description": "The campaign's leads that can still get an email and that this rule matches now. Leads whose provider is still\nbeing detected are in no group. Counts cover at most 100,000 leads.",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "SenderRoutingModel": {
        "type": "object",
        "properties": {
          "allInboxes": {
            "type": "boolean",
            "description": "True: the campaign's inboxes are live (\"All inboxes\"), so inboxes connected later join it. False: a saved list.\nChange it with `PUT /v1/campaigns/{campaignId}/inboxes` (`allInboxes: true`, or `inboxIds`)."
          },
          "rules": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SenderRouteRuleModel"
            },
            "description": "The rules, by provider name.",
            "nullable": true
          },
          "everyoneElse": {
            "$ref": "#/components/schemas/SenderRouteGroupModel"
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SenderRoutingWarningModel"
            },
            "description": "What would make leads wait: see Ken.Scraper.API.Canonical.SenderRoutingWarningModel.Code.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-5225: a campaign's sender routing. Rules send the first email to prospects on one mailbox provider or security\ngateway only from the rule's domains and inboxes; prospects no rule matches go from the inboxes no rule claims\n(Everyone else). Follow-ups stay on the first email's inbox."
      },
      "SenderRoutingWarningModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "`rule_no_inbox`: none of the rule's inboxes can send, so its leads wait. `everyone_else_no_inbox`: every\n            sendable inbox is in a rule, so leads no rule matches wait. `rule_slow`: the rule needs more than 5 days to\n            reach its leads at its daily capacity.",
            "nullable": true
          },
          "provider": {
            "type": "string",
            "description": "The rule's provider slug. Omitted for `everyone_else_no_inbox`.",
            "nullable": true
          },
          "leadCount": {
            "type": "integer",
            "description": "The leads that wait or are slow to reach.",
            "format": "int32",
            "nullable": true
          },
          "days": {
            "type": "integer",
            "description": "`rule_slow` only: leads divided by daily capacity, rounded up.",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SendingCapacityForecastDayModel": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "description": "The UTC day, YYYY-MM-DD.",
            "nullable": true
          },
          "capacity": {
            "type": "integer",
            "description": "Emails the workspace's healthy inboxes can send in a day.",
            "format": "int32"
          },
          "sent": {
            "type": "integer",
            "description": "Today only: emails already sent since UTC midnight. Left out on later days.",
            "format": "int32",
            "nullable": true
          },
          "planned": {
            "type": "integer",
            "description": "Emails already queued or planned for that day. The planner plans about 36 hours ahead, so later days fill in as it reaches them.",
            "format": "int32"
          },
          "remaining": {
            "type": "integer",
            "description": "Capacity minus sent and planned, never below 0.",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "SendingCapacityForecastModel": {
        "type": "object",
        "properties": {
          "calculatedAt": {
            "type": "string",
            "description": "When Kenso computed the forecast (UTC).",
            "format": "date-time"
          },
          "days": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SendingCapacityForecastDayModel"
            },
            "description": "UTC today, tomorrow and the day after, in that order.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "The workspace's sending forecast for UTC today and the next two days (DEV-5222)."
      },
      "SequenceRestoreModel": {
        "type": "object",
        "properties": {
          "newVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "versionWarning": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SequenceVariableModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "syntax": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SequenceVariablesModel": {
        "type": "object",
        "properties": {
          "variables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceVariableModel"
            },
            "nullable": true
          },
          "senderVariables": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SequenceVariableModel"
            },
            "nullable": true
          },
          "usage": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SequenceVersionModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "versionNumber": {
            "type": "integer",
            "format": "int32"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdByEmail": {
            "type": "string",
            "nullable": true
          },
          "isRevert": {
            "type": "boolean"
          },
          "revertedFromVersionId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "revertedFromVersionNumber": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "revertedFromCreatedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ShareAccessRowModel": {
        "type": "object",
        "properties": {
          "label": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ShareActivityModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "type": {
            "type": "string",
            "description": "share_created, share_viewed, approved, changes_requested, commented, decision_undone, share_submitted, ...",
            "nullable": true
          },
          "shareItemId": {
            "type": "integer",
            "description": "The share item it is about. Omitted for share-wide entries.",
            "format": "int64",
            "nullable": true
          },
          "actorKind": {
            "type": "string",
            "description": "user, reviewer or system.",
            "nullable": true
          },
          "actorName": {
            "type": "string",
            "nullable": true
          },
          "actorUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "data": {
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ShareCommentModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "shareItemId": {
            "type": "integer",
            "format": "int64"
          },
          "anchor": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "authorName": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ShareItemModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "approved, changes_requested, not_reviewed, view_only or changed.",
            "nullable": true
          },
          "approvalItemId": {
            "type": "integer",
            "description": "The external approval item behind it.",
            "format": "int64"
          },
          "decidedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decidedByName": {
            "type": "string",
            "nullable": true
          },
          "decisionComment": {
            "type": "string",
            "nullable": true
          },
          "commentCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false
      },
      "ShareKindStatusModel": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "description": "leads, copy, settings, icp, report or plan.",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "approved, changes_requested, not_reviewed, view_only or changed.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ShareListResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShareModel"
            },
            "nullable": true
          },
          "pagination": {
            "$ref": "#/components/schemas/CanonicalPagination"
          },
          "changesRequestedCount": {
            "type": "integer",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "GET /v1/shares: the list envelope plus the workspace's count of shares with changes requested (the nav badge)."
      },
      "ShareModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "type": "string",
            "description": "Who the share is for, shown on the page. Defaults to the workspace name.",
            "nullable": true
          },
          "url": {
            "type": "string",
            "description": "The link to send: `https://<app host>/s/<token>`.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "accountIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "The accounts of the account plans, in the order picked. Omitted without plans.",
            "nullable": true
          },
          "kinds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "What is shared, in page order: leads, copy, settings, icp, report, plan.",
            "nullable": true
          },
          "permission": {
            "type": "string",
            "description": "view, comment or approve.",
            "nullable": true
          },
          "expiry": {
            "type": "string",
            "description": "7_days, 30_days or never, counted from creation.",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "isExpired": {
            "type": "boolean"
          },
          "holdLaunch": {
            "type": "boolean"
          },
          "recurringReport": {
            "type": "boolean"
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "not_opened, viewed, n_of_m_approved, changes_requested or approved.",
            "nullable": true
          },
          "approvedCount": {
            "type": "integer",
            "description": "Kinds approved, for \"n of m approved\". Always 0 on view and comment shares.",
            "format": "int32"
          },
          "kindCount": {
            "type": "integer",
            "format": "int32"
          },
          "changesRequestedCount": {
            "type": "integer",
            "format": "int32"
          },
          "kindStatuses": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShareKindStatusModel"
            },
            "nullable": true
          },
          "viewCount": {
            "type": "integer",
            "format": "int32"
          },
          "firstViewedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastViewedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submittedByName": {
            "type": "string",
            "nullable": true
          },
          "lastReportSentAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "createdByUserId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastActivityAt": {
            "type": "string",
            "description": "The share's latest activity: created, viewed, a decision, a comment, a reminder, a report sent or the\nreview sent.",
            "format": "date-time"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShareItemModel"
            },
            "description": "Detail only.",
            "nullable": true
          },
          "comments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShareCommentModel"
            },
            "description": "Detail only: the comments left through this share, oldest first.",
            "nullable": true
          },
          "access": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShareAccessRowModel"
            },
            "description": "Detail only: the Access rows (\"They can\", \"Expires\", \"Launch\", \"Repeats\", \"Branding\").",
            "nullable": true
          },
          "activity": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShareActivityModel"
            },
            "description": "Detail only: the share's log, newest first, at most 50 entries.",
            "nullable": true
          },
          "alreadyEmailedRecipients": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Create only: the recipients the link was not emailed to, because a share link email from this workspace reached\nthem in the last 24 hours. Send them the link yourself. Omitted when nobody was left out.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A share link (DEV-1765). The list leaves out the detail fields (items, comments, access, activity)."
      },
      "SharePublicBrandModel": {
        "type": "object",
        "properties": {
          "productName": {
            "type": "string",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "nullable": true
          },
          "faviconUrl": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SharePublicItemModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "kind": {
            "type": "string",
            "description": "leads, copy, settings, icp, report or plan.",
            "nullable": true
          },
          "title": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "approved, changes_requested, not_reviewed, view_only or changed.",
            "nullable": true
          },
          "canUndo": {
            "type": "boolean",
            "description": "True when the reviewer can undo this item's decision (made from this link, review not sent, no newer\nversion, and not an approved copy, lead list or settings of a campaign already running)."
          },
          "decidedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "decidedByName": {
            "type": "string",
            "nullable": true
          },
          "decisionComment": {
            "type": "string",
            "nullable": true
          },
          "snapshot": {
            "description": "The frozen snapshot: the campaign settings, ICP, weekly report or account plan object (camelCase, as\nbuilt when the share was created); copy and lead lists use the DEV-1526 snapshot shapes."
          },
          "comments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShareCommentModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SharePublicModel": {
        "type": "object",
        "properties": {
          "brand": {
            "$ref": "#/components/schemas/SharePublicBrandModel"
          },
          "workspaceName": {
            "type": "string",
            "nullable": true
          },
          "workspaceLogoUrl": {
            "type": "string",
            "description": "DEV-4548: the workspace's wide Logo, else its square Icon. Omitted when it has neither.",
            "nullable": true
          },
          "workspaceIconUrl": {
            "type": "string",
            "description": "DEV-4548: the workspace's square Icon, else its wide Logo. Omitted when it has neither.",
            "nullable": true
          },
          "shareName": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "type": "string",
            "nullable": true
          },
          "senderName": {
            "type": "string",
            "description": "The member who created the share. Omitted when unknown.",
            "nullable": true
          },
          "campaignName": {
            "type": "string",
            "nullable": true
          },
          "permission": {
            "type": "string",
            "description": "view, comment or approve.",
            "nullable": true
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "holdLaunch": {
            "type": "boolean"
          },
          "isSubmitted": {
            "type": "boolean"
          },
          "submittedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "submittedByName": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "not_opened, viewed, n_of_m_approved, changes_requested or approved.",
            "nullable": true
          },
          "approvedCount": {
            "type": "integer",
            "format": "int32"
          },
          "kindCount": {
            "type": "integer",
            "format": "int32"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SharePublicItemModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What /s/<token> shows (and Preview as the reviewer)."
      },
      "ShareReminderModel": {
        "type": "object",
        "properties": {
          "shareId": {
            "type": "integer",
            "format": "int64"
          },
          "recipientCount": {
            "type": "integer",
            "description": "The recipients emailed: those that are email addresses, less Ken.Scraper.API.Canonical.ShareReminderModel.AlreadyEmailedRecipients. Names are\nnever emailed.",
            "format": "int32"
          },
          "remindedAt": {
            "type": "string",
            "format": "date-time"
          },
          "alreadyEmailedRecipients": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The recipients left out because a share link email from this workspace reached them in the last 24 hours.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SharedImageModel": {
        "type": "object",
        "properties": {
          "imageKey": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`pending`, `ready` or `failed`.",
            "nullable": true
          },
          "errorCode": {
            "type": "string",
            "nullable": true
          },
          "previewUrl": {
            "type": "string",
            "nullable": true
          },
          "previewExpiresAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A shared image variable's image. `previewUrl` is a presigned link for the app, valid until `previewExpiresAt`."
      },
      "SignalIntakeModel": {
        "type": "object",
        "properties": {
          "acceptedCount": {
            "type": "integer",
            "description": "Signals queued by this call.",
            "format": "int32"
          },
          "duplicateCount": {
            "type": "integer",
            "description": "Signals skipped because their dedupKey was already queued in the last 24 hours.",
            "format": "int32"
          },
          "isSynthetic": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "StartCallRequest": {
        "type": "object",
        "properties": {
          "personId": {
            "type": "integer",
            "description": "Required. The person to call.",
            "format": "int64",
            "nullable": true
          },
          "toNumber": {
            "type": "string",
            "description": "One of the person's phones; absent calls their primary phone.",
            "nullable": true
          },
          "fromNumberId": {
            "type": "integer",
            "description": "The workspace's number to call from; absent takes the member's, else the workspace's first.",
            "format": "int64",
            "nullable": true
          },
          "callTaskId": {
            "type": "integer",
            "description": "The person's open call task this call works.",
            "format": "int64",
            "nullable": true
          },
          "touchId": {
            "type": "integer",
            "description": "The person's call touch this call works. Send callTaskId or touchId, not both.",
            "format": "int64",
            "nullable": true
          },
          "recording": {
            "type": "boolean",
            "description": "Record the call where the workspace's settings and the law allow it. Default true.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "POST /v1/calling/calls body (Dialer 05)."
      },
      "StringFilter": {
        "type": "object",
        "properties": {
          "contains": {
            "type": "string",
            "nullable": true
          },
          "notContains": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "StudioPinModel": {
        "type": "object",
        "properties": {
          "versionId": {
            "type": "integer",
            "format": "int64"
          },
          "templateId": {
            "type": "integer",
            "description": "The version's template; null when the version is gone.",
            "format": "int64",
            "nullable": true
          },
          "state": {
            "type": "string",
            "description": "`ok`, or `stale` when the version is no longer published, not an email, or its template\n            was deleted. A stale step sends its stored fallback.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SubmitSavedListBody": {
        "type": "object",
        "properties": {
          "icpTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Replaces the list's ICP tags when given: up to 20, each up to 50 characters. An empty array clears them.",
            "nullable": true
          },
          "description": {
            "type": "string",
            "description": "Replaces the list's description when given: up to 2000 characters, not blank.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Library submission body (DEV-4391). Both fields are optional; an empty body submits the list as it is."
      },
      "SuggestedTimeModel": {
        "type": "object",
        "properties": {
          "startAt": {
            "type": "string",
            "format": "date-time"
          },
          "endAt": {
            "type": "string",
            "format": "date-time"
          },
          "localStartAt": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "SuggestedTimesModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "bookingTool": {
            "type": "string",
            "nullable": true
          },
          "hostMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "meetingTypeId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "routingReason": {
            "type": "string",
            "nullable": true
          },
          "timeZone": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "times": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SuggestedTimeModel"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TagAssignmentBulkItemResult": {
        "type": "object",
        "properties": {
          "index": {
            "type": "integer",
            "format": "int32"
          },
          "status": {
            "type": "string",
            "description": "`assigned` (bulk-create) or `removed` (bulk-delete), else `not_found`,\n            `validation_failed`, `permission_denied`, or `failed`.",
            "nullable": true
          },
          "error": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TagAssignmentBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "integer",
            "format": "int32"
          },
          "failed": {
            "type": "integer",
            "format": "int32"
          },
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagAssignmentBulkItemResult"
            },
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Result of `POST /v1/tags/{tagId}/assignments/bulk-create` and `bulk-delete`.\n`results` is in request order; `index` is the item's position in `items`."
      },
      "TagAssignmentModel": {
        "type": "object",
        "properties": {
          "tagId": {
            "type": "integer",
            "format": "int64"
          },
          "entityType": {
            "type": "string",
            "nullable": true
          },
          "entityId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "messageId": {
            "type": "string",
            "nullable": true
          },
          "conversationId": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TagAssignmentRequest": {
        "type": "object",
        "properties": {
          "entityType": {
            "type": "string",
            "nullable": true
          },
          "entityId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "messageId": {
            "type": "string",
            "nullable": true
          },
          "conversationId": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TagModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "entityTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "isConfig": {
            "type": "boolean"
          },
          "isSystem": {
            "type": "boolean"
          },
          "systemKey": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "usage": {
            "$ref": "#/components/schemas/TagUsageModel"
          },
          "entityIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Only with `entityType=campaign&includeEntityIds=true`; absent otherwise. The ids, ascending, of the workspace's\nlive campaigns that carry the tag.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 341,
          "name": "Hot lead",
          "description": "Asked for a call or pricing",
          "color": "#FFD6A5",
          "type": "contact",
          "entityTypes": [
            "contact",
            "reply"
          ],
          "isConfig": false,
          "isSystem": false,
          "createdAt": "2026-09-23T15:02:11Z",
          "updatedAt": "2026-10-14T09:41:27Z"
        }
      },
      "TagUsageModel": {
        "type": "object",
        "properties": {
          "campaignCount": {
            "type": "integer",
            "format": "int32"
          },
          "contactCount": {
            "type": "integer",
            "format": "int32"
          },
          "replyCount": {
            "type": "integer",
            "description": "Email messages carrying the tag.",
            "format": "int32"
          },
          "linkedinConversationCount": {
            "type": "integer",
            "format": "int32"
          },
          "inboxCount": {
            "type": "integer",
            "format": "int32"
          },
          "domainCount": {
            "type": "integer",
            "format": "int32"
          },
          "accountCount": {
            "type": "integer",
            "format": "int32"
          },
          "linkedinAccountCount": {
            "type": "integer",
            "description": "Live LinkedIn accounts of the workspace carrying the tag (DEV-4051).",
            "format": "int32"
          }
        },
        "additionalProperties": false,
        "description": "Live assignments of a tag in the workspace. Deleted assignments and deleted targets do not count."
      },
      "TestFireTriggerRequest": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "integer",
            "description": "The contact the sample signal is about. Required; must be in the workspace.",
            "format": "int64",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "description": "The campaign the sample came from, for the trigger's audience filter. Optional; must be in the workspace.",
            "format": "int64",
            "nullable": true
          },
          "payload": {
            "description": "The signal payload, a JSON object of at most 16 KB, e.g. `{\"clickedUrl\":\"https://...\"}`.",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "description": "When the sample happened (ISO 8601, within the last 365 days). Omitted means now.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "A sample signal for a trigger test fire. Its type is the trigger's own signal type."
      },
      "TestInboundWebhookMappingRequest": {
        "type": "object",
        "properties": {
          "samplePayloadJson": {
            "type": "string",
            "nullable": true
          },
          "mapping": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookAssignment"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TestPromptRequest": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "flow": {
            "type": "string",
            "nullable": true
          },
          "sampleSize": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "segmentId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "modelOverrides": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/PromptTestOverrideRequest"
            },
            "nullable": true
          },
          "excludeContactIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TestSendSequenceRequest": {
        "type": "object",
        "properties": {
          "contactId": {
            "type": "integer",
            "format": "int64"
          },
          "targetEmails": {
            "type": "string",
            "nullable": true
          },
          "senderEmailId": {
            "type": "integer",
            "format": "int64"
          },
          "language": {
            "type": "string",
            "description": "DEV-1922: send as a contact in this language (fr-FR, de) gets the steps; omitted sends in the contact's own\nlanguage. The campaign's source language sends the source text.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ThreadAddressRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ThreadBulkError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ThreadBulkFailure": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "error": {
            "$ref": "#/components/schemas/ThreadBulkError"
          }
        },
        "additionalProperties": false
      },
      "ThreadBulkResult": {
        "type": "object",
        "properties": {
          "succeeded": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "failed": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadBulkFailure"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ThreadCampaignCountModel": {
        "type": "object",
        "properties": {
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "campaignName": {
            "type": "string",
            "description": "Omitted when the campaign has no name.",
            "nullable": true
          },
          "threadCount": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "ThreadCountsModel": {
        "type": "object",
        "properties": {
          "allCount": {
            "type": "integer",
            "description": "Distinct threads in the requested tab, as `GET /v1/threads` lists them with the same tab filters.",
            "format": "int64"
          },
          "accountsCount": {
            "type": "integer",
            "description": "Threads in the requested tab that are linked to an account.",
            "format": "int64"
          },
          "campaignsCount": {
            "type": "integer",
            "description": "Threads in the requested tab that belong to a campaign.",
            "format": "int64"
          },
          "campaigns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadCampaignCountModel"
            },
            "description": "Every campaign with a thread in the inbox, newest activity first. `threadCount` is 0 when none is in the requested tab.",
            "nullable": true
          },
          "toReplyCount": {
            "type": "integer",
            "description": "Threads on the To Reply tab.",
            "format": "int64"
          },
          "unreadCount": {
            "type": "integer",
            "description": "Inbox threads with an unread inbound message.",
            "format": "int64"
          },
          "latestMessageAt": {
            "type": "string",
            "description": "Newest inbound message in the inbox. Omitted when the inbox is empty.",
            "format": "date-time",
            "nullable": true
          },
          "inboxChangedAt": {
            "type": "string",
            "description": "When the inbox last changed: the newest insert or update of an inbound email (a reply synced\nlate, the classifier moving a reply between tabs, a read), or the newest update of a LinkedIn\nconversation whose last message is inbound. Poll it and refetch when it changes; it is not a\nmessage time. Omitted when the inbox is empty.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Thread counts for the inbox sidebar (DEV-1751). Email and LinkedIn together."
      },
      "ThreadDraftMirrorModel": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "Plain text with line breaks.",
            "nullable": true
          },
          "language": {
            "type": "string",
            "description": "ISO 639-1 code of Ken.Scraper.API.Canonical.ThreadDraftMirrorModel.Text (`en`).",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ThreadDraftModel": {
        "type": "object",
        "properties": {
          "threadId": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "authorSource": {
            "type": "string",
            "description": "Who last wrote the draft (DEV-2537): `user`, a person in the dashboard, or `agent`, an agent, MCP token or\nAPI key. An agent never overwrites a person's draft.",
            "nullable": true
          },
          "mirror": {
            "$ref": "#/components/schemas/ThreadDraftMirrorModel"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "ThreadMessageAwaitingApprovalModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "threadId": {
            "type": "string",
            "nullable": true
          },
          "approvalId": {
            "type": "string",
            "nullable": true
          },
          "approverMemberId": {
            "type": "integer",
            "description": "The seat owner who must approve it. Names come from `/v1/members`.",
            "format": "int64",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-6464: `202` of `POST /v1/threads/{threadId}/messages` when an agent's or API key's LinkedIn reply through a\nseat another member connected waits for that member's approval. Nothing was sent. `approvalId` is the item in\n`GET /v1/approvals` (type `reply.linkedin`), visible and decidable only by `approverMemberId`."
      },
      "ThreadMessageHeldModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "nullable": true
          },
          "clientApprovalItemId": {
            "type": "integer",
            "format": "int64"
          },
          "threadId": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "`POST /v1/threads/{threadId}/messages` 202: the reply waits for external approval. Nothing was sent."
      },
      "ThreadMessageModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "threadId": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "direction": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          },
          "extractedText": {
            "type": "string",
            "description": "Inbound email only: the sender's own words, with quoted history, signature, mobile footer and sign-off removed.\nOmitted for outbound email, LinkedIn, and a message with no readable body. `body` keeps the full text.",
            "nullable": true
          },
          "language": {
            "type": "string",
            "description": "DEV-5312, inbound messages only: the message's ISO 639-1 code, the classifier's language, else detected from its\nown words. Omitted when unknown and on outbound messages.",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time"
          },
          "warnings": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadMessageWarningModel"
            },
            "description": "Set on `POST /v1/threads/{threadId}/messages` when the reply went out past a safeguard the caller confirmed,\nand on `POST /v1/threads` when the new thread went out from an inbox that has not finished warming up.\nOmitted otherwise.",
            "nullable": true
          },
          "senderName": {
            "type": "string",
            "nullable": true
          },
          "fromName": {
            "type": "string",
            "nullable": true
          },
          "fromEmailAddress": {
            "type": "string",
            "nullable": true
          },
          "htmlBody": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadTagModel"
            },
            "nullable": true
          },
          "to": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "cc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "bcc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "openCount": {
            "type": "integer",
            "description": "Outbound email only: open-pixel hits excluding known proxies and crawlers. 0 when not opened or not tracked.",
            "format": "int32",
            "nullable": true
          },
          "rawOpenCount": {
            "type": "integer",
            "description": "Outbound email only: raw open-pixel hits, proxies and prefetch included. Always at least Ken.Scraper.API.Canonical.ThreadMessageModel.OpenCount.",
            "format": "int32",
            "nullable": true
          },
          "firstOpenedAt": {
            "type": "string",
            "description": "Outbound email only: the first recorded open.",
            "format": "date-time",
            "nullable": true
          },
          "lastOpenedAt": {
            "type": "string",
            "description": "Outbound email only: the latest recorded open.",
            "format": "date-time",
            "nullable": true
          },
          "referral": {
            "$ref": "#/components/schemas/ThreadReferralModel"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MessageAttachmentModel"
            },
            "description": "DEV-4082, `GET /v1/threads/{threadId}/messages`, email only: the message's files, inline images included.\nDownload one with `GET /v1/attachments/{id}/content`. Omitted when the message has none.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "id": "msg_ZW1haWw6NDAyMjg0LjJAZXhhbXBsZS5jb20",
          "threadId": "thr_ZW1haWw6NDAyMjg0LjFAZXhhbXBsZS5jb20",
          "channel": "email",
          "direction": "inbound",
          "subject": "Re: Onboarding new engineers at Northwind Labs",
          "body": "Thanks Alex, this is timely. We are hiring 12 engineers this quarter. Could we talk Thursday afternoon?\n\nAmanda\n\nOn Tue, Oct 13, 2026 at 9:04 AM Alex Rivera <alex@mail.example.com> wrote:\n> Hi Amanda, following up on this.",
          "extractedText": "Thanks Alex, this is timely. We are hiring 12 engineers this quarter. Could we talk Thursday afternoon?",
          "language": "en",
          "occurredAt": "2026-10-13T16:22:05Z",
          "senderName": "Amanda Chen",
          "fromName": "Amanda Chen",
          "fromEmailAddress": "amanda.chen@northwind.example.com",
          "htmlBody": "<p>Thanks Alex, this is timely. We are hiring 12 engineers this quarter.</p><p>Could we talk Thursday afternoon?</p><p>Amanda</p>",
          "tags": [
            {
              "id": 341,
              "name": "Hot lead",
              "color": "#FFD6A5"
            }
          ],
          "to": [
            {
              "name": "Alex Rivera",
              "address": "alex@mail.example.com"
            }
          ]
        }
      },
      "ThreadMessageWarningModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "A stable token: `suppressed_contact_overridden` (on a reply) or `warmup_not_ready` (on a new thread).",
            "nullable": true
          },
          "reason": {
            "type": "string",
            "description": "With `suppressed_contact_overridden`, the suppression reason: `do_not_contact`, `blocklisted` or\n`unsubscribed`. With `warmup_not_ready`, the warmup state: `too_young` or `unconfirmed`.",
            "nullable": true
          },
          "fix": {
            "type": "string",
            "description": "With `warmup_not_ready`: what to do. The email was sent; pick a warmer inbox for the next one.",
            "nullable": true
          },
          "readyAt": {
            "type": "string",
            "description": "With `warmup_not_ready` and `too_young`: the day the inbox is ready (UTC).",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ThreadModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "channel": {
            "type": "string",
            "nullable": true
          },
          "direction": {
            "type": "string",
            "description": "`GET /v1/threads` only: who sent the newest message the row stands for, `inbound` (the contact) or\n            `outbound` (the workspace). On an outbound email row `fromName` is ours, so the contact is the first\n            of `to`; a LinkedIn row's `fromName` is the contact either way (DEV-4276). Omitted from threads.get\n            and updates, whose messages each carry their own direction.",
            "nullable": true
          },
          "campaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "contactId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "accountId": {
            "type": "integer",
            "description": "The account this thread belongs to: the account whose touch the thread is (the newest touch's, DEV-1606), on\nlists and threads.get. threads.get falls back to the account on which the thread's contact (matched by email,\nelse LinkedIn URL) is a stakeholder. Absent when there is none, outside the caller's account scope, or while\nthe accounts feature is off for the caller.",
            "format": "int64",
            "nullable": true
          },
          "accountName": {
            "type": "string",
            "description": "The name of Ken.Scraper.API.Canonical.ThreadModel.AccountId. Absent with it.",
            "nullable": true
          },
          "replyTouchId": {
            "type": "integer",
            "description": "DEV-2537, an email thread that is an account touch's thread, on lists and threads.get: that account's open reply\ntouch (reason `reply`; `planned`, `drafted`, `awaiting_approval` or `approved`) answering a\nmessage in this thread, the newest when there are several. Send the reply by approving it\n(`POST /v1/touches/{touchId}/approve`) so the account's plan records it. Absent with Ken.Scraper.API.Canonical.ThreadModel.AccountId,\non LinkedIn threads, when there is none or the read failed, and from updates.",
            "format": "int64",
            "nullable": true
          },
          "hasDraft": {
            "type": "boolean",
            "description": "DEV-2537: a reply draft is saved on the thread, whoever wrote it; `GET /v1/threads/{threadId}/draft` returns\nit. On lists, threads.get and updates. False when the draft read failed."
          },
          "draftAuthor": {
            "type": "string",
            "description": "Who last wrote that draft: `user` (a person in the dashboard) or `agent` (an agent, MCP token or API\nkey). Absent without a draft.",
            "nullable": true
          },
          "inboxId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "preview": {
            "type": "string",
            "nullable": true
          },
          "isRead": {
            "type": "boolean"
          },
          "isArchived": {
            "type": "boolean"
          },
          "isSaved": {
            "type": "boolean"
          },
          "interest": {
            "type": "string",
            "nullable": true
          },
          "reminderAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "lastMessageAt": {
            "type": "string",
            "format": "date-time"
          },
          "waitingSince": {
            "type": "string",
            "description": "`GET /v1/threads` only: when the contact's newest message arrived, on any tab. It is the wait on a reply\n            only on the To Reply tab: a thread marked done or archived still carries it. A thread we answered whose\n            reminder came due is on To Reply for that reminder, so it carries the reminder's due time, not the time of the\n            reply we answered. Omitted when the newest message is ours and no reminder is due, and from threads.get\n            (DEV-5202).",
            "format": "date-time",
            "nullable": true
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          },
          "senderName": {
            "type": "string",
            "description": "The same name as `fromName`.",
            "nullable": true
          },
          "fromName": {
            "type": "string",
            "description": "Email: the sender of the thread's newest message, ours when that message is outbound. LinkedIn: the contact's name, on\nlists and threads.get (DEV-6565); absent when the conversation names nobody.",
            "nullable": true
          },
          "fromEmailAddress": {
            "type": "string",
            "nullable": true
          },
          "htmlBody": {
            "type": "string",
            "nullable": true
          },
          "tags": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadTagModel"
            },
            "nullable": true
          },
          "to": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "cc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "bcc": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ThreadRecipientModel"
            },
            "nullable": true
          },
          "scheduledMessages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ScheduledMessageModel"
            },
            "description": "`GET /v1/threads/{threadId}` only, email: messages queued on this thread that have not sent yet\n            (`scheduled`, `sending`, or `awaiting_approval` with `approverMemberId`, DEV-2043), oldest\n            due first. An empty list means none are pending. Omitted from lists, from updates, and when the pending\n            read failed.",
            "nullable": true
          },
          "referral": {
            "$ref": "#/components/schemas/ThreadReferralModel"
          },
          "language": {
            "type": "string",
            "description": "DEV-5312: the ISO 639-1 code of the newest inbound message (the classifier's language, else detected from the\nmessage's own words). On `GET /v1/threads` an email row carries its own message's, so a row whose newest\nmessage is ours has none. Omitted when unknown.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "example": {
          "id": "thr_ZW1haWw6NDAyMjg0LjFAZXhhbXBsZS5jb20",
          "channel": "email",
          "direction": "inbound",
          "campaignId": 4821,
          "contactId": 90125,
          "hasDraft": false,
          "inboxId": 5530,
          "subject": "Re: Onboarding new engineers at Northwind Labs",
          "preview": "Thanks Alex, this is timely. We are hiring 12 engineers this quarter. Could we talk Thursday afternoon?",
          "isRead": false,
          "isArchived": false,
          "isSaved": false,
          "interest": "interested",
          "lastMessageAt": "2026-10-13T16:22:05Z",
          "waitingSince": "2026-10-13T16:22:05Z",
          "updatedAt": "2026-10-13T16:22:05Z",
          "senderName": "Amanda Chen",
          "fromName": "Amanda Chen",
          "fromEmailAddress": "amanda.chen@northwind.example.com",
          "htmlBody": "<p>Thanks Alex, this is timely. We are hiring 12 engineers this quarter.</p><p>Could we talk Thursday afternoon?</p><p>Amanda</p>",
          "tags": [
            {
              "id": 341,
              "name": "Hot lead",
              "color": "#FFD6A5"
            }
          ],
          "to": [
            {
              "name": "Alex Rivera",
              "address": "alex@mail.example.com"
            }
          ],
          "language": "en"
        }
      },
      "ThreadRecipientModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "address": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "ThreadReferralModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "email": {
            "type": "string",
            "nullable": true
          },
          "linkedinUrl": {
            "type": "string",
            "nullable": true
          },
          "phone": {
            "type": "string",
            "description": "DEV-3501: the number as the reply writes it. A person with a phone and no email or LinkedIn URL cannot be added as\na lead; the app shows the number for the recruiter to add them by hand.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "DEV-1274 (contract C8): the person a recruiting reply points to when its interest is `referral`. Every part is\ncopied from the reply itself; a part the reply does not give is null. The app shows it as a candidate to add (Task 24)."
      },
      "ThreadTagModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          },
          "systemKey": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TrackingLinkModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "nullable": true
          },
          "textValue": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdBy": {
            "type": "integer",
            "format": "int64"
          },
          "modifiedAt": {
            "type": "string",
            "format": "date-time"
          },
          "modifiedBy": {
            "type": "integer",
            "format": "int64"
          }
        },
        "additionalProperties": false
      },
      "TranslationModel": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "The translated plain text, with the input's line breaks.",
            "nullable": true
          },
          "sourceLanguage": {
            "type": "string",
            "description": "ISO 639-1 code of the input text, or `und` when the model named none.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TriggerFiringModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "triggerId": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "contactId": {
            "type": "integer",
            "format": "int64"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "suppressionReason": {
            "type": "string",
            "nullable": true
          },
          "attemptCount": {
            "type": "integer",
            "format": "int32"
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "firedAt": {
            "type": "string",
            "format": "date-time"
          },
          "processedAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TriggerModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "campaignId": {
            "type": "integer",
            "format": "int64"
          },
          "stagingCampaignId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "signalType": {
            "type": "string",
            "nullable": true
          },
          "tier": {
            "type": "string",
            "nullable": true
          },
          "parameters": {
            "type": "string",
            "nullable": true
          },
          "audienceFilter": {
            "type": "string",
            "nullable": true
          },
          "cooldownMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "maxAgeMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "priority": {
            "type": "integer",
            "format": "int32"
          },
          "stopSourceSequence": {
            "type": "boolean"
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false
      },
      "TriggerParameterFieldDto": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "defaultValue": {
            "nullable": true
          },
          "required": {
            "type": "boolean"
          },
          "min": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "max": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "options": {
            "type": "array",
            "items": { },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TriggerSchemaModel": {
        "type": "object",
        "properties": {
          "signalType": {
            "type": "string",
            "nullable": true
          },
          "catalogKey": {
            "type": "string",
            "nullable": true
          },
          "subject": {
            "type": "string",
            "nullable": true
          },
          "defaultParameters": {
            "type": "object",
            "additionalProperties": {
              "nullable": true
            },
            "nullable": true,
            "example": {
              "id": 90125,
              "first_name": "Amanda",
              "last_name": "Chen",
              "full_name": "Amanda Chen",
              "email": "amanda.chen@northwind-labs.com",
              "email_validity": "Verified",
              "title": "VP of Engineering",
              "profile_url": "https://www.linkedin.com/in/amanda-chen-northwind",
              "company_name": "Northwind Labs",
              "company_domain": "northwind-labs.com",
              "campaign_name": "Q2 outbound — Series B SaaS founders"
            }
          },
          "defaultCooldownMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "defaultMaxAgeMinutes": {
            "type": "integer",
            "format": "int32"
          },
          "defaultPriority": {
            "type": "integer",
            "format": "int32"
          },
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TriggerParameterFieldDto"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TriggerStatsModel": {
        "type": "object",
        "properties": {
          "fired": {
            "type": "integer",
            "format": "int32"
          },
          "exported": {
            "type": "integer",
            "format": "int32"
          },
          "suppressed": {
            "type": "integer",
            "format": "int32"
          },
          "suppressionBreakdown": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "format": "int32"
            },
            "nullable": true
          },
          "lastFiredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TriggerTestFireCheckModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "passed": {
            "type": "boolean"
          },
          "message": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "TriggerTestFireModel": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "description": "Always `trigger_test_fire`.",
            "nullable": true
          },
          "triggerId": {
            "type": "integer",
            "format": "int64"
          },
          "signalType": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "The trigger's status: `active`, `paused` or `archived`.",
            "nullable": true
          },
          "shouldFire": {
            "type": "boolean",
            "description": "True only when every check passed: the trigger would create a firing for this sample now."
          },
          "rejectedBy": {
            "type": "string",
            "description": "The first check that failed, or null.",
            "nullable": true
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TriggerTestFireCheckModel"
            },
            "description": "In pipeline order: `status`, `audience_filter`, `parameters`, `cooldown`. Every check runs.",
            "nullable": true
          },
          "evidence": {
            "description": "What the firing would carry as evidence, when the sample met the parameters; else null.",
            "nullable": true
          },
          "scheduledFor": {
            "type": "string",
            "description": "When the evaluator delays the firing, the time it would be scheduled for; else null.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What a saved trigger would do with one sample signal. Nothing is published, fired, sent or charged."
      },
      "UnsubscribeEventSubscriptionRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "arguments": {
            "type": "object",
            "additionalProperties": { },
            "nullable": true
          },
          "delivery": {
            "$ref": "#/components/schemas/EventSubscriptionUnsubscribeDelivery"
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/event-subscriptions/unsubscribe` (SEP-3415 `events/unsubscribe`)."
      },
      "UpdateBlocklistEntryRequest": {
        "type": "object",
        "properties": {
          "reason": {
            "type": "string",
            "description": "Why the value is blocked, at most 200 characters. Null or blank clears it.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateBlocklistRuleBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "stages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "accountTypes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "reason": {
            "type": "string",
            "nullable": true
          },
          "enabled": {
            "type": "boolean",
            "nullable": true
          },
          "position": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "releaseAfterDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "crmListId": {
            "type": "string",
            "nullable": true
          },
          "crmLifecycles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateBookingLinkBody": {
        "type": "object",
        "properties": {
          "availability": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AvailabilityScheduleModel"
              }
            ],
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateCampaignRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "contactLimit": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "Present only so a caller who sends `status` is rejected. Lifecycle changes are actions.",
            "nullable": true
          },
          "sendingDays": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int32"
            },
            "description": "0 = Sunday through 6 = Saturday. Omit to leave the stored days unchanged.",
            "nullable": true
          },
          "sendingStartTime": {
            "type": "string",
            "nullable": true
          },
          "sendingEndTime": {
            "type": "string",
            "nullable": true
          },
          "sendingTimezone": {
            "type": "string",
            "nullable": true
          },
          "maxEmailsPerDay": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "ownerMemberId": {
            "type": "integer",
            "description": "New campaign owner: the id of an active member of this workspace. Omit (or send null) to leave the\nowner unchanged. The owner cannot be cleared.",
            "format": "int64",
            "nullable": true
          },
          "stopOnReply": {
            "type": "boolean",
            "nullable": true
          },
          "trackClicks": {
            "type": "boolean",
            "nullable": true
          },
          "trackOpens": {
            "type": "boolean",
            "nullable": true
          },
          "unsubscribeLink": {
            "type": "boolean",
            "nullable": true
          },
          "protectAccountPlays": {
            "type": "boolean",
            "description": "DEV-1520: skip people in active account plays. Omit to leave it unchanged.",
            "nullable": true
          },
          "rampUpDays": {
            "type": "integer",
            "description": "DEV-1661: ramp-up length in scheduled sending days, 0 (no ramp) to 30. Omit to leave it unchanged.",
            "format": "int32",
            "nullable": true
          },
          "stopCompanyOnReply": {
            "type": "boolean",
            "description": "DEV-1661: a reply also stops every other contact at the lead's company. The same stored value as\n`stopSequenceForCompanyOnReply` in the LinkedIn settings. Omit to leave it unchanged.",
            "nullable": true
          },
          "groupSameCompanySends": {
            "type": "boolean",
            "description": "DEV-1661: coworkers at one company share a send day. Omit to leave it unchanged.",
            "nullable": true
          },
          "newLeadsFirst": {
            "type": "boolean",
            "description": "DEV-3762: first emails take the campaign's capacity ahead of its follow-ups. Omit to leave it unchanged.",
            "nullable": true
          },
          "bookingMeetingTypeId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "replyTo": {
            "type": "string",
            "nullable": true
          },
          "excludedCountries": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "DEV-5236: the countries this campaign never sends to, as ISO 3166-1 alpha-2 codes or country names (\"DE\",\n\"Germany\"). Replaces the stored list; an empty list clears it. Omit (or send null) to leave it unchanged.",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "nullable": true
          },
          "roleId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          },
          "sourceLanguage": {
            "type": "string",
            "description": "A market pack locale (`fr-FR`) or a language with a primary pack (`en`).",
            "nullable": true
          },
          "languageMode": {
            "type": "string",
            "description": "`source_only` or `auto`.",
            "nullable": true
          },
          "enabledLanguages": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "formalityOverrides": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "languageFallback": {
            "type": "string",
            "description": "`source` or `hold`.",
            "nullable": true
          },
          "mode": {
            "type": "string",
            "description": "DEV-15: `batch` or `trigger`. Batch to trigger converts the campaign; trigger to batch is refused\n(`mode_one_way`). Omit to leave it unchanged.",
            "nullable": true
          },
          "autoLaunchWhenReady": {
            "type": "boolean",
            "description": "DEV-15: launch automatically once the campaign is ready. Needs the launch permission; refused once the campaign\nlaunched or auto-launch already ran. Omit to leave it unchanged.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Partial campaign update. Unknown JSON members are a 400. `status` is a known\nmember only so a lifecycle patch is rejected instead of ignored."
      },
      "UpdateContactAiLineRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "The new line, 1 to 4,000 characters. It gets the cleanup a generated line gets (emoji removed, dashes\nnormalized, spaces collapsed, line breaks kept) and must be at most 1,000 characters after it.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `PATCH /v1/contacts/{contactId}/ai-lines/{aiLineId}` (DEV-4637)."
      },
      "UpdateContactBody": {
        "type": "object",
        "properties": {
          "firstName": {
            "type": "string",
            "description": "First name. Null clears it.",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "description": "Last name. Null clears it.",
            "nullable": true
          },
          "title": {
            "type": "string",
            "description": "Job title. Null clears it.",
            "nullable": true
          },
          "linkedInUrl": {
            "type": "string",
            "description": "LinkedIn profile URL. Null clears it.",
            "nullable": true
          },
          "location": {
            "type": "string",
            "description": "Location. Null clears it.",
            "nullable": true
          },
          "email": {
            "type": "string",
            "description": "Primary email address. Null removes it; an invalid address is refused.",
            "nullable": true
          },
          "isQualified": {
            "type": "boolean",
            "description": "Whether the contact is qualified. Must be true or false: null is refused."
          },
          "doNotContact": {
            "type": "boolean",
            "description": "Whether the contact must never be contacted. Must be true or false: null is refused."
          },
          "outreachLanguage": {
            "type": "string",
            "description": "Outreach language set by hand: a locale whose language has a market pack or a country entry, such as fr-FR, es-MX or\nde. It is locked, so no import, enrichment or reply replaces it. Null clears and unlocks it.",
            "nullable": true
          },
          "customVariables": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "nullable": true
            },
            "description": "Merge into the contact's custom variables. A null or empty value removes that key. Omit to leave them unchanged.",
            "nullable": true
          },
          "customImageUrl": {
            "type": "string",
            "description": "The lead's own image, shown in emails as `{{custom_image}}`: a public https URL of at most 2048 characters that\nKenso downloads and hosts. Empty or null clears it. Needs campaign images on the workspace.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `PATCH /v1/contacts/{contactId}`. Every property is optional: an absent property leaves that field\nunchanged, and `null` clears a string field. Any other property is `400 validation_failed`."
      },
      "UpdateCrmConnectionBody": {
        "type": "object",
        "properties": {
          "settings": {
            "$ref": "#/components/schemas/UpdateCrmSettingsBody"
          },
          "syncObjects": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/CrmSyncObjectPatch"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateCrmInboundPeopleBody": {
        "type": "object",
        "properties": {
          "enabled": {
            "type": "boolean",
            "nullable": true
          },
          "filters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmInboundPeopleFilterBody"
            },
            "nullable": true
          },
          "leadStatus": {
            "type": "string",
            "nullable": true
          },
          "defaultOwnerMemberId": {
            "type": "integer",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateCrmSettingsBody": {
        "type": "object",
        "properties": {
          "createRecordsWhen": {
            "type": "string",
            "nullable": true
          },
          "salesforcePersonMode": {
            "type": "string",
            "nullable": true
          },
          "emailLogging": {
            "type": "string",
            "nullable": true
          },
          "pipelineExternalId": {
            "type": "string",
            "nullable": true
          },
          "stageMap": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            },
            "nullable": true
          },
          "importDaily": {
            "type": "boolean",
            "nullable": true
          },
          "skipOpenOpportunities": {
            "type": "boolean",
            "nullable": true
          },
          "blockCustomers": {
            "type": "boolean",
            "nullable": true
          },
          "pauseOnRepActivityDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "staticListPerCampaign": {
            "type": "boolean",
            "nullable": true
          },
          "listSources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CrmListSourceBody"
            },
            "nullable": true
          },
          "inboundPeople": {
            "$ref": "#/components/schemas/UpdateCrmInboundPeopleBody"
          }
        },
        "additionalProperties": false
      },
      "UpdateCustomVariableRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "useAsAiContext": {
            "type": "boolean",
            "nullable": true
          },
          "isRequiredForSending": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateImageVariableRequest": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "Not changeable: sending it is 400.",
            "nullable": true
          },
          "kind": {
            "type": "string",
            "description": "Not changeable: sending it is 400.",
            "nullable": true
          },
          "prompt": {
            "type": "string",
            "nullable": true
          },
          "references": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "model": {
            "type": "string",
            "nullable": true
          },
          "size": {
            "type": "string",
            "nullable": true
          },
          "quality": {
            "type": "string",
            "nullable": true
          },
          "spellingCheck": {
            "type": "boolean",
            "nullable": true
          },
          "requiredForSending": {
            "type": "boolean",
            "nullable": true
          },
          "enabled": {
            "type": "boolean",
            "description": "per_prospect standing order. False is always allowed and keeps the existing images.",
            "nullable": true
          },
          "altText": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "JSON body of `PATCH /v1/campaigns/{campaignId}/image-variables/{variableKey}`. An absent field is unchanged;\n`prompt` and `altText` are cleared by null or blank. `key` and `kind` never change: sending\neither is 400 on that field."
      },
      "UpdateInboundWebhookRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "samplePayloadJson": {
            "type": "string",
            "nullable": true
          },
          "mapping": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WebhookAssignment"
            },
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "app": {
            "type": "string",
            "description": "A `people` webhook only: `zapier`, `make` or `n8n`, or `null` to clear it.",
            "nullable": true
          },
          "defaultOwnerMemberId": {
            "type": "integer",
            "description": "A `people` webhook only: a member of the workspace, or `null` to clear it.",
            "format": "int64",
            "nullable": true
          },
          "createAccounts": {
            "type": "boolean",
            "description": "A `people` webhook only: `true` or `false`.",
            "nullable": true
          },
          "createPerson": {
            "type": "boolean",
            "description": "A `workflow` webhook only: `true` or `false`.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "PATCH body. Absent properties stay unchanged."
      },
      "UpdateInfraFindingRequest": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`open` (reopen), `snoozed` or `ignored`. Required.",
            "nullable": true
          },
          "snoozedUntil": {
            "type": "string",
            "description": "When a snoozed finding opens again (ISO 8601 UTC), in the future and at most a year ahead. Required with\n`snoozed`, refused with the other statuses.",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `PATCH /v1/infra/findings/{findingId}` and `PATCH /v1/admin/infra/findings/{findingId}` (DEV-6199)."
      },
      "UpdateLinkedInAccountBody": {
        "type": "object",
        "properties": {
          "displayName": {
            "type": "string",
            "nullable": true
          },
          "timezone": {
            "type": "string",
            "description": "An IANA time zone, for example `Europe/Bucharest`. An empty string clears it (UTC).",
            "nullable": true
          },
          "workingHours": {
            "type": "string",
            "description": "The stored working-hours JSON (keyed mon..sun). Prefer Ken.Scraper.API.Dtos.UpdateLinkedInAccountBody.WorkingHoursSchedule; send one of the two.",
            "nullable": true
          },
          "workingHoursSchedule": {
            "$ref": "#/components/schemas/LinkedInWeeklySchedule"
          },
          "dailyInviteCap": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "dailyMessageCap": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "dailyVisitCap": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "paused": {
            "type": "boolean",
            "description": "`true` pauses outreach from the account (campaign invites, messages, InMails, profile visits,\n            withdrawals, approved Accounts notes) and keeps the original `pausedAt` when it is already paused.\n            `false` resumes it, and its waiting actions continue where they stopped. The autonomous reply agent's\n            sends wait too. A person's replies from the Inbox and inbox sync keep running while paused. Omit or send\n            `null` to leave the pause unchanged.",
            "nullable": true
          },
          "importConnections": {
            "type": "boolean",
            "description": "`true` imports the seat's connections into Accounts as people and accounts; `false` stops new imports and\n            keeps what was imported (DEV-5778). Only the member who connected the seat or a workspace admin may send it, and\n            only while linkedin_connections_import is on. Omit or send `null` to leave it unchanged.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateLocalizationRequest": {
        "type": "object",
        "properties": {
          "subjectLine": {
            "type": "string",
            "description": "The localized subject. An email localization only.",
            "nullable": true
          },
          "bodyContent": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of PATCH /v1/campaigns/{campaignId}/localizations/{localizationId}. Absent keeps the stored text."
      },
      "UpdateMeetingTypeBody": {
        "type": "object",
        "properties": {
          "lengthMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "locationKind": {
            "type": "string",
            "nullable": true
          },
          "locationDetail": {
            "type": "string",
            "nullable": true
          },
          "minimumNoticeMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bookingWindowDays": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bufferBeforeMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "bufferAfterMinutes": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "dailyCap": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "reminderEnabled": {
            "type": "boolean",
            "nullable": true
          },
          "reminderText": {
            "type": "string",
            "nullable": true
          },
          "questions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MeetingTypeQuestionInput"
            },
            "nullable": true
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "slug": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isSecret": {
            "type": "boolean",
            "nullable": true
          },
          "isEnabled": {
            "type": "boolean",
            "nullable": true
          },
          "isDefault": {
            "type": "boolean",
            "nullable": true
          },
          "availability": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AvailabilityScheduleModel"
              }
            ],
            "nullable": true
          },
          "hostMemberIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateOutboundSiteRequest": {
        "type": "object",
        "properties": {
          "mainSiteUrl": {
            "type": "string",
            "nullable": true
          },
          "brandName": {
            "type": "string",
            "nullable": true
          },
          "contactEmail": {
            "type": "string",
            "nullable": true
          },
          "legalName": {
            "type": "string",
            "nullable": true
          },
          "postalAddress": {
            "type": "string",
            "nullable": true
          },
          "showMainSiteLink": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "PATCH /v1/outbound-site (DEV-1095). A field left out keeps its value; null clears a text field."
      },
      "UpdateSavedListBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "visibility": {
            "type": "string",
            "nullable": true
          },
          "icpTags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateSegmentRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "segmentationType": {
            "type": "string",
            "nullable": true
          },
          "abTestPercentage": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "sortOrder": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "filterCriteria": {
            "$ref": "#/components/schemas/CampaignSegmentFilterCriteriaDTO"
          }
        },
        "additionalProperties": false,
        "description": "PATCH body. Absent properties stay unchanged. A JSON null clears description and ab-test percentage."
      },
      "UpdateShareInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "company": {
            "type": "string",
            "nullable": true
          },
          "recipients": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "expiry": {
            "type": "string",
            "nullable": true
          },
          "holdLaunch": {
            "type": "boolean",
            "nullable": true
          },
          "recurringReport": {
            "type": "boolean",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpdateTrackingLinkRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "domainName": {
            "type": "string",
            "nullable": true
          },
          "textValue": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "PATCH body. Absent properties stay unchanged. JSON null clears `textValue`."
      },
      "UpdateWebhookEndpointRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isDisabled": {
            "type": "boolean",
            "nullable": true
          },
          "app": {
            "type": "string",
            "description": "`zapier`, `make` or `n8n`. Omitted: unchanged. An empty string clears the tag.",
            "nullable": true
          },
          "campaignIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "Campaign filter. Omitted: unchanged. Empty: every campaign.",
            "nullable": true
          },
          "classifications": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Classification filter (snake_case). Omitted: unchanged. Empty: every classification.",
            "nullable": true
          },
          "isBatched": {
            "type": "boolean",
            "description": "Batch delivery of the high-volume types. Omitted: unchanged.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UpsertEventSubscriptionRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "The MCP event type, such as `meeting.booked`.",
            "nullable": true
          },
          "arguments": {
            "type": "object",
            "additionalProperties": { },
            "description": "The event's filters: `campaignId`, `classification`, as the type supports them.",
            "nullable": true
          },
          "delivery": {
            "$ref": "#/components/schemas/EventSubscriptionDeliveryRequest"
          },
          "cursor": {
            "type": "string",
            "description": "Where delivery starts for a new or lapsed subscription. Null: from now. Ignored on a live one.",
            "nullable": true
          },
          "maxAgeMs": {
            "type": "integer",
            "description": "Start no earlier than this many milliseconds ago.",
            "format": "int64",
            "nullable": true
          },
          "ttlMs": {
            "type": "integer",
            "description": "The suggested lifetime in milliseconds. The grant is at most one hour.",
            "format": "int64",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Body of `POST /v1/event-subscriptions` (SEP-3415 `events/subscribe`)."
      },
      "UpsertThreadDraftRequest": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "string",
            "nullable": true
          },
          "body": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UsedByCampaignModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "The campaign's status as `GET /v1/campaigns` returns it.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "UsedByModel": {
        "type": "object",
        "properties": {
          "campaigns": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsedByCampaignModel"
            },
            "description": "Live campaigns (scheduled, sending or launching, not deleted) assigned this inbox or LinkedIn\naccount, ordered by id. Empty when none.",
            "nullable": true
          },
          "accounts": {
            "type": "boolean",
            "description": "True when the 1:1 Accounts lane uses it. For an inbox, the member's primary inbox\n(`isPrimary`). For a LinkedIn account, the member who connected it owns at least one live\naccount in the workspace: an account's LinkedIn touches default to the seat its owner connected\n(DEV-1618).",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "What an inbox or LinkedIn account is used for (DEV-2026): the live campaigns that send through it,\nand whether the 1:1 Accounts lane does."
      },
      "WebhookAssignment": {
        "type": "object",
        "properties": {
          "target": {
            "type": "string",
            "nullable": true
          },
          "variableName": {
            "type": "string",
            "nullable": true
          },
          "useAsAiContext": {
            "type": "boolean"
          },
          "fallback": {
            "type": "boolean",
            "nullable": true
          },
          "source": {
            "$ref": "#/components/schemas/WebhookAssignmentSource"
          }
        },
        "additionalProperties": false
      },
      "WebhookAssignmentSource": {
        "type": "object",
        "properties": {
          "kind": {
            "type": "string",
            "nullable": true
          },
          "path": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          },
          "labelPath": {
            "type": "string",
            "nullable": true
          },
          "valuePath": {
            "type": "string",
            "nullable": true
          },
          "label": {
            "type": "string",
            "nullable": true
          },
          "labelsPath": {
            "type": "string",
            "nullable": true
          },
          "idPath": {
            "type": "string",
            "nullable": true
          },
          "index": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WebhookDeliveryModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "messageId": {
            "type": "string",
            "nullable": true
          },
          "eventType": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "nullable": true
          },
          "responseStatusCode": {
            "type": "integer",
            "format": "int32",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WebhookDeliveryResendModel": {
        "type": "object",
        "properties": {
          "deliveryId": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WebhookEndpointModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "url": {
            "type": "string",
            "nullable": true
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "isDisabled": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "app": {
            "type": "string",
            "description": "`zapier`, `make` or `n8n` when the endpoint belongs to that app; null otherwise.",
            "nullable": true
          },
          "health": {
            "type": "string",
            "description": "`active`, `failing` (the newest attempt failed) or `disabled`. Omitted, with\n            `lastDelivery` and `failedAttempts`, when the delivery log could not be read.",
            "nullable": true
          },
          "lastDelivery": {
            "$ref": "#/components/schemas/WebhookLastDeliveryModel"
          },
          "failedAttempts": {
            "type": "integer",
            "description": "Failed attempts since the newest success among the latest 10 attempts; 0 unless failing.",
            "format": "int32",
            "nullable": true
          },
          "campaignIds": {
            "type": "array",
            "items": {
              "type": "integer",
              "format": "int64"
            },
            "description": "The campaign filter: the endpoint receives only events of these campaigns. Empty: every event. A filtered endpoint\nnever receives an event that has no campaign.",
            "nullable": true
          },
          "classifications": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The classification filter (snake_case `reply.classified` labels): the endpoint receives only events whose reply\nhas one of them. Empty: every event. A filtered endpoint never receives an event without a reply classification.\nWith Ken.Scraper.API.Canonical.WebhookEndpointModel.CampaignIds, both must match.",
            "nullable": true
          },
          "isBatched": {
            "type": "boolean",
            "description": "The high-volume event types arrive as `<type>.batch` deliveries of up to 100 events\n(`{eventType, eventId, timestamp, clientId, count, events}`), never one by one."
          }
        },
        "additionalProperties": false,
        "example": {
          "id": "ep_2bKq8yZ0aB3cD4eF5gH6iJ7kL8m",
          "url": "https://hooks.example.com/kenso/replies",
          "events": [
            "reply.classified"
          ],
          "description": "Interested replies into our CRM",
          "isDisabled": false,
          "createdAt": "2026-09-23T15:02:11Z",
          "health": "active",
          "lastDelivery": {
            "occurredAt": "2026-10-13T16:22:41Z",
            "status": "success",
            "responseStatusCode": 200,
            "eventType": "reply.classified"
          },
          "failedAttempts": 0,
          "campaignIds": [
            4821
          ],
          "classifications": [
            "interested"
          ],
          "isBatched": false
        }
      },
      "WebhookEndpointTestAttemptModel": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "`success`, `pending` or `fail`.",
            "nullable": true
          },
          "responseStatusCode": {
            "type": "integer",
            "description": "The endpoint's HTTP status; omitted when it never answered.",
            "format": "int32",
            "nullable": true
          },
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WebhookEndpointTestModel": {
        "type": "object",
        "properties": {
          "messageId": {
            "type": "string",
            "description": "The Svix message id (`msg_`) of the test delivery.",
            "nullable": true
          },
          "eventType": {
            "type": "string",
            "nullable": true
          },
          "attempt": {
            "$ref": "#/components/schemas/WebhookEndpointTestAttemptModel"
          }
        },
        "additionalProperties": false
      },
      "WebhookEventTypeModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "The type endpoints subscribe to, e.g. `reply.received`.",
            "nullable": true
          },
          "group": {
            "type": "string",
            "description": "The group key Settings sections the catalog by.",
            "nullable": true
          },
          "groupLabel": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "mcp": {
            "type": "boolean",
            "description": "Offered as an MCP event."
          },
          "filters": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The delivery filters the type supports: `campaign`, `classification`, `channel`.",
            "nullable": true
          },
          "highVolume": {
            "type": "boolean",
            "description": "Fires often enough per workspace to be worth batching."
          },
          "sample": {
            "description": "An example body with made-up values, shaped like a real delivery of this type."
          }
        },
        "additionalProperties": false,
        "description": "One webhook event type from the catalog (DEV-4029)."
      },
      "WebhookLastDeliveryModel": {
        "type": "object",
        "properties": {
          "occurredAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "status": {
            "type": "string",
            "description": "`success`, `pending` or `fail`.",
            "nullable": true
          },
          "responseStatusCode": {
            "type": "integer",
            "description": "The endpoint's HTTP status; omitted when it never answered.",
            "format": "int32",
            "nullable": true
          },
          "eventType": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WebhookRecoverModel": {
        "type": "object",
        "properties": {
          "since": {
            "type": "string",
            "format": "date-time"
          },
          "until": {
            "type": "string",
            "format": "date-time"
          }
        },
        "additionalProperties": false,
        "description": "The window a recover resends; Svix resends its failed deliveries in the background."
      },
      "WebhookSigningSecretModel": {
        "type": "object",
        "properties": {
          "secret": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WhiteLabelClientSeatsModel": {
        "type": "object",
        "properties": {
          "readReplies": {
            "type": "boolean",
            "description": "\"Clients can read replies\": the default of the Client built-in permission template. True = Inbox\nedit plus reply, false = Inbox off. A workspace that edited its Client template keeps its edit.\nDefault false."
          }
        },
        "additionalProperties": false,
        "description": "The client-seat switches of a master (DEV-1786). Returned in `GET /v1/white-label` and by\n`PATCH /v1/white-label/client-seats`."
      },
      "WorkflowReadinessCheckModel": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "description": "`contacts_imported`, `trigger_definitions_configured`, `email_sequence_configured`,\n            `email_sequence_versions_unique`, `ai_variables_resolved`, `campaign_name_configured`,\n            `contact_limit_configured`, or `sending_schedule_configured`. Clients tolerate new codes.",
            "nullable": true
          },
          "message": {
            "type": "string",
            "nullable": true
          },
          "isPassed": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "WorkflowReadinessModel": {
        "type": "object",
        "properties": {
          "canStart": {
            "type": "boolean",
            "description": "True when every check passed."
          },
          "checks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkflowReadinessCheckModel"
            },
            "description": "Every check that applies to the campaign, passed or not.",
            "nullable": true
          }
        },
        "additionalProperties": false,
        "description": "Whether a campaign's enrichment, verification, and AI workflows can start. Independent of\nKen.Scraper.API.Canonical.LaunchReadinessModel, which covers sending."
      },
      "WorkspaceBrandModel": {
        "type": "object",
        "properties": {
          "productName": {
            "type": "string",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "nullable": true
          },
          "faviconUrl": {
            "type": "string",
            "nullable": true
          },
          "appUrl": {
            "type": "string",
            "description": "Base URL of the app for this workspace, for example `https://app.ken.so`.",
            "nullable": true
          },
          "accentColor": {
            "type": "string",
            "description": "Accent color, `#RRGGBB` uppercase (the master's for a child). Omitted when the Kenso default applies.",
            "nullable": true
          },
          "clientSeats": {
            "$ref": "#/components/schemas/WhiteLabelClientSeatsModel"
          },
          "clientApprovalLinks": {
            "type": "boolean",
            "description": "The master's \"Client approval links\" switch, as `clientApprovalLinks` on `GET /v1/white-label`\n(the master's for a child, DEV-2160). Omitted when it could not be read.",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WorkspaceModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "website": {
            "type": "string",
            "nullable": true
          },
          "linkedinCompanyUrl": {
            "type": "string",
            "nullable": true
          },
          "companyContext": {
            "type": "string",
            "nullable": true
          },
          "ownerLink": {
            "type": "string",
            "description": "Only on the staff create response (`POST /v1/admin/workspaces`) when `ownerEmail` was sent:\n`linked`, `already_member`, `user_not_found` or `failed`.",
            "nullable": true
          },
          "logoUrl": {
            "type": "string",
            "description": "The square Icon. Omitted when none.",
            "nullable": true
          },
          "wordmarkUrl": {
            "type": "string",
            "description": "DEV-4548: the wide Logo (wordmark). Omitted when none.",
            "nullable": true
          },
          "pauseSendingOnUsHolidays": {
            "type": "boolean"
          },
          "replyRateBenchmark": {
            "type": "number",
            "description": "DEV-5223: the reply rate benchmark, in percent (2.5 is 2.5%). Null when not set.",
            "format": "double",
            "nullable": true
          },
          "replyRateTarget": {
            "type": "number",
            "description": "DEV-5223: the reply rate target, in percent. Null when not set.",
            "format": "double",
            "nullable": true
          },
          "positiveReplyRateBenchmark": {
            "type": "number",
            "description": "DEV-5223: the interested-reply rate benchmark, in percent. Null when not set.",
            "format": "double",
            "nullable": true
          },
          "positiveReplyRateTarget": {
            "type": "number",
            "description": "DEV-5223: the interested-reply rate target, in percent. Null when not set.",
            "format": "double",
            "nullable": true
          },
          "meetingsPerMonthBenchmark": {
            "type": "number",
            "description": "DEV-5223: meetings booked per month, benchmark. Null when not set.",
            "format": "double",
            "nullable": true
          },
          "meetingsPerMonthTarget": {
            "type": "number",
            "description": "DEV-5223: meetings booked per month, target. Null when not set.",
            "format": "double",
            "nullable": true
          },
          "replyTo": {
            "type": "string",
            "description": "DEV-2528: the Reply-To on every Kenso Sequencer cold send of this workspace, unless the campaign sets its own.\nA connected inbox of this workspace that Kenso reads replies from. Omitted when none.",
            "nullable": true
          },
          "parentWorkspaceId": {
            "type": "integer",
            "description": "The white-label master of this workspace. Omitted for a master.",
            "format": "int64",
            "nullable": true
          },
          "isChild": {
            "type": "boolean",
            "description": "True when this workspace is a white-label child."
          },
          "hasClients": {
            "type": "boolean",
            "description": "DEV-3956: true when this workspace has at least one active member with the Client role or at least one\nchild workspace."
          },
          "brand": {
            "$ref": "#/components/schemas/WorkspaceBrandModel"
          },
          "isDemo": {
            "type": "boolean",
            "description": "Kenso's demo workspace (`client.is_demo`, MAR-6): the Ken Demo switcher marks it for staff, and staff-only Studio chat and Agent team open to its members."
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 812,
          "name": "Northwind Outbound",
          "isActive": true,
          "website": "https://northwind-outbound.example.com",
          "companyContext": "Northwind Outbound runs cold email for B2B SaaS companies selling to engineering leaders in North America.",
          "logoUrl": "https://cdn.example.com/workspaces/812/icon.png",
          "pauseSendingOnUsHolidays": true,
          "replyRateBenchmark": 3.5,
          "replyRateTarget": 5,
          "positiveReplyRateBenchmark": 1.2,
          "positiveReplyRateTarget": 2,
          "meetingsPerMonthBenchmark": 8,
          "meetingsPerMonthTarget": 12,
          "replyTo": "replies@mail.example.com",
          "isChild": false,
          "hasClients": false,
          "isDemo": false
        }
      },
      "WorkspaceSummaryModel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "isActive": {
            "type": "boolean"
          },
          "logoUrl": {
            "type": "string",
            "description": "The square Icon. Omitted when none.",
            "nullable": true
          },
          "wordmarkUrl": {
            "type": "string",
            "description": "DEV-4548: the wide Logo (wordmark). Omitted when none.",
            "nullable": true
          },
          "parentWorkspaceId": {
            "type": "integer",
            "description": "The white-label master of this workspace. Omitted for a master.",
            "format": "int64",
            "nullable": true
          },
          "brandHostname": {
            "type": "string",
            "description": "The master's verified custom hostname. Omitted when the workspace is unbranded.",
            "nullable": true
          },
          "isDemo": {
            "type": "boolean",
            "description": "Kenso's demo workspace (`client.is_demo`, MAR-6): the Ken Demo switcher marks it for staff, and staff-only Studio chat and Agent team open to its members."
          }
        },
        "additionalProperties": false,
        "example": {
          "id": 812,
          "name": "Northwind Outbound",
          "isActive": true,
          "logoUrl": "https://cdn.example.com/workspaces/812/icon.png",
          "isDemo": false
        }
      }
    },
    "securitySchemes": {
      "Bearer": {
        "type": "http",
        "description": "Enter: Bearer {your Kenso API key}. Create one in the Kenso app under Settings > Integrations > API Keys.",
        "scheme": "bearer",
        "bearerFormat": "Opaque API key"
      }
    }
  },
  "security": [
    { }
  ],
  "tags": [
    {
      "name": "access-requests",
      "description": "Access requests (DEV-1654, spec section 10). Served only when `Ken-Version: 1.1`, in the workspace from\n`X-Ken-Workspace-Id`, and only while the `permissions` flag is on there (otherwise 404).\nA member asks for a page, a feature or credits; a member who manages members grants or declines; the requester\ncan cancel. Granting writes an override on the requester. Create, list and cancel are public exposure (any\nmember asks, sees and cancels their own); grant and decline keep the class's internal tier."
    },
    {
      "name": "agent-team",
      "description": "The workspace side of the agent team (DEV-3671) that every workspace with `agent_templates` has, with or without\nthe in-app team: its target and runway, the template catalog, the lead runway an agent in the workspace's own AI tool\nreads, the bounded actions (with their undo) that agent asks for, the changes since it last looked and the proposals it\nmakes. GETs need Campaigns view, writes Campaigns edit; listing proposals needs Campaigns edit and Approve. The staff\nteam routes are `CanonicalAgentTeamStaffController`."
    },
    {
      "name": "ai-line-holds",
      "description": "Canonical AI line check holds (DEV-918). Served only when `Ken-Version: 1.1`. A campaign with AI Line Check\n(AI workflow 8) grades each contact's personalization lines before they are saved; when the lines fail and the\nrewrite fails too, the contact is held: its lines are kept but not sent. List the held contacts here and approve\none to send its lines as they are. To regenerate a held contact instead, use\n`POST /v1/contacts/{contactId}/ai-lines/regenerate` or\n`POST /v1/campaigns/{campaignId}/ai-runs/reset-contacts` with `flow: personalization`; either clears the\nhold and the contact goes through the check again. These routes work whatever the check's mode is."
    },
    {
      "name": "ai-lines",
      "description": "Canonical contact AI lines (DEV-4637): read, correct or regenerate the personalized lines one lead sends with.\nServed only when `Ken-Version: 1.1`, and only while the `ai_line_edit` flag is on for the workspace\n(else `404`). Reading needs campaigns View; editing needs campaigns Edit, so the Client template never writes."
    },
    {
      "name": "ai-runs",
      "description": "Canonical AI runs. Served only when `Ken-Version: 1.1`.\nThe execute job id is a GUID, so status is read here rather than through the numeric jobs facade."
    },
    {
      "name": "analytics",
      "description": "Canonical reporting. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`. Every action only reads, the `query` POST included, so the\nclass needs Campaigns view whatever the HTTP method (a by-method declaration would make the POST need edit)."
    },
    {
      "name": "attachments",
      "description": "Canonical attachments. Served only when `Ken-Version: 1.1`.\nUpload is multipart `file` plus a canonical email `messageId`."
    },
    {
      "name": "auto-pauses",
      "description": "Canonical list of the pauses Ken applied on its own (DEV-2025). Served only when\n`Ken-Version: 1.1`. The workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "autonomous-reply-settings",
      "description": "Canonical autonomous reply settings. Served only when `Ken-Version: 1.1`.\nOne resource per workspace. The workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "blocklist-entries",
      "description": "Canonical blocklist entries. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "blocklist-rules",
      "description": "Canonical blocklist rules (DEV-3903): block the domains of the accounts that have a live opportunity in chosen stages\nof Kenso's CRM, or that have one of chosen account types (DEV-4105). From the workspace's connected CRM (DEV-4027): the\nrecords in chosen lifecycle stages (a company's domain; a contact's company domain, or its email when it has only a\nfree email domain) and the members of one CRM list (a contact list's people by email, a company list's domains). Kenso\nkeeps the entries in step: one is added when an account reaches a rule's stage or type, or a record its lifecycle\nstage or list, and comes off once no enabled rule matches it, which includes a rule's release window passing since the\ndeal closed (DEV-4359) and a person leaving the list (read again about every 15 minutes). Entries a rule adds have\n`source: rule` on `GET /v1/blocklist-entries`; a manual, own-domain or customer entry is never changed. Dark\nbehind the `blocklist_rules` flag (no staff bypass); the CRM criteria also behind `blocklist_rules_crm`."
    },
    {
      "name": "booking-links",
      "description": "Canonical booking links (DEV-1959): a person's prefilled link to a member's booking page, or a single-use link.\nBehind the scheduler flag. Any member who can see the Calendar page links to their own page; admins to anyone's."
    },
    {
      "name": "bookings",
      "description": "A rep who left (DEV-1964): reassign or cancel their upcoming bookings, 20 per call. Admins only (the members feature).\nA filter-based bulk call that answers per booking instead of returning a job: a job is out of proportion for a handful of\nmeetings, and 20 per call stays inside the gateway's 120-second cluster."
    },
    {
      "name": "brands",
      "description": "Anonymous white-label brand lookup (DEV-1216). The frontend calls it before sign-in to brand a\ncustom host and to pick the Auth0 organization for login. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "bug-reports",
      "description": "Bug reports from users and their agents (DEV-6152): each one is a new issue in Kenso's Linear Alerts project. Served only\nwhen `Ken-Version: 1.1`, and dark behind the `bug_reports` workspace flag (404 while it is off)."
    },
    {
      "name": "calling",
      "description": "Canonical built-in dialer (Dialer 02 and 05, DEV-3327): calling settings, phone numbers bought in Kenso for credits,\ncall rates, the monthly calling spend limit, and browser calls with their WebRTC tokens. Served only when\n`Ken-Version: 1.1` and the `calling` feature flag is on (404 otherwise). Every member reads; writes and the\nnumber search need the `workspace_settings` feature; calls need edit on the Accounts page. The workspace comes\nfrom `X-Ken-Workspace-Id`."
    },
    {
      "name": "campaign-compliance",
      "description": "A campaign's consent-first countries and their launch acknowledgements (DEV-1923). Served only with\n`Ken-Version: 1.1` and the `multilingual_outreach` workspace flag (404 while it is off). The read needs the\nCampaigns page, the acknowledgement Campaigns edit. A campaign outside the workspace is 404."
    },
    {
      "name": "campaign-images",
      "description": "Stored campaign images (DEV-6700): the current images of some leads of a campaign for the leads table and lead sheet,\nand one image with a fresh preview URL. Served only with `Ken-Version: 1.1` and the `campaign_images`\nworkspace flag (404 while it is off). Needs the Campaigns page. A campaign or image outside the workspace is 404.\nPreviews are presigned links that work for 1 hour, never an email host."
    },
    {
      "name": "campaign-languages",
      "description": "A campaign's languages (DEV-1921): its language settings, the market packs it can enable and its contacts per outreach\nlanguage. Served only with `Ken-Version: 1.1` and the `multilingual_outreach` workspace flag (404 while it is\noff). Needs the Campaigns page. A campaign outside the workspace is 404."
    },
    {
      "name": "campaign-localizations",
      "description": "A campaign's step text in each language it enables (DEV-1921): list the localizations, queue their writing, and\napprove, rewrite or edit one. Served only with `Ken-Version: 1.1` and the `multilingual_outreach` workspace\nflag (404 while it is off). Reads need the Campaigns page, writes Campaigns edit. A campaign outside the workspace is\n404."
    },
    {
      "name": "campaigns",
      "description": "Canonical campaigns resource. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`. Status changes go through actions."
    },
    {
      "name": "cli-logins",
      "description": "The Kenso CLI's browser login. The CLI starts a login (`create`, no credential), the person opens\n`verificationUrl` signed in to Kenso and approves it for a workspace (`get`, `approve`, `deny`),\nand the CLI polls `token` (no credential) until it picks up a Kenso API key, once."
    },
    {
      "name": "client-approvals",
      "description": "Canonical external approvals (DEV-1526): the partner's side of the no-login client portal. Served only\nwith `Ken-Version: 1.1`, behind the `client_approvals` feature flag (404 when off). The\nworkspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "companies",
      "description": "Canonical companies resource. Served only when `Ken-Version: 1.1`.\nRead-only. The workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "company-data",
      "description": "Canonical company data (DEV-2013): a company's brand, technologies and funding by its website domain, from free Kenso\ndata. Served only when `Ken-Version: 1.1`. The data is global: the workspace header admits the caller and\nscopes the `searchBrowseRows` quota, where an answer with Kenso Search data counts one row like a Search lookup."
    },
    {
      "name": "contact-exports",
      "description": "Canonical contact exports. Served only when `Ken-Version: 1.1`.\nCreate returns a `contact_export` job. The file is produced from the stored filters\nwhen `downloadUrl` is read, so either API replica can serve it."
    },
    {
      "name": "contact-fields",
      "description": "Canonical contact field catalog. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "contact-imports",
      "description": "Buyer previews (DEV-5566): the company-list mode of the CSV import. A list of companies becomes the buyers Kenso\nSearch finds at each, matched to the campaign's ICP, as a free preview the user prunes before anything is added.\nServed only with `Ken-Version: 1.1` and the `csv_buyer_preview` feature flag (404 otherwise). Declares\nwhat a contact import does: Campaigns edit and the Import feature. The workspace comes from\n`X-Ken-Workspace-Id`."
    },
    {
      "name": "contacts",
      "description": "Canonical contacts. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "credits",
      "description": "Canonical credits (DEV-1544). Served only when `Ken-Version: 1.1`. Every amount is millicredits\n(1 credit = 1,000 millicredits = $0.02). The class admits any signed-in caller. Balance and estimates need a workspace\nmember (the balance's billing details need the `billing` feature), model usage needs a member with the\n`ask` feature (agent runs report usage as the end user), and the ledger and auto top-up need the\n`billing` feature. The workspace\ncomes from `X-Ken-Workspace-Id` on every action except the static rate card."
    },
    {
      "name": "crm-connections",
      "description": "Canonical CRM connections (DEV-1280): one CRM per workspace. Served only with `Ken-Version: 1.1`, behind the\n`ingestion` flag (404 when off). Reads need accounts view; connect, settings and disconnect also need the\nintegrations feature (workspace admins)."
    },
    {
      "name": "crm-sync",
      "description": "CRM sync control (DEV-1280): preview, Import now, health, Needs attention, field mapping, and reads of the CRM's\nfields, pipelines, lists and records. Served only with `Ken-Version: 1.1`, behind the `ingestion` flag.\nReads need accounts view; writes also need the integrations feature (workspace admins)."
    },
    {
      "name": "custom-variables",
      "description": "Canonical campaign custom variables. Served only when `Ken-Version: 1.1`.\nKeys go through M:Ken.Scraping.Application.Common.CampaignCustomVariableRules.NormalizeKey(System.String)."
    },
    {
      "name": "domain-health-checks",
      "description": "Canonical domain health checks. Served only when `Ken-Version: 1.1`.\nReplaces `POST /v1/domains/health/run`. Poll with\n`GET /v1/jobs/{jobId}?type=domain_health`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "domains",
      "description": "Canonical domains. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "email-copy-grades",
      "description": "Grades one sequencer email with the client-system Jev copy questions, or one LinkedIn\nstep with the LinkedIn rubric. Served only when `Ken-Version: 1.1`. A saved grade\nfor the same `subjectKey` and channel is returned until `refresh` is true."
    },
    {
      "name": "email-copy-lints",
      "description": "DEV-5221: checks one sequencer email against the email-review rules in code: word bands, the four first-line\nchecks, the bridge rule, spam-word tiers, links, merge fields and AI variable coverage. No model runs and nothing\nis saved, so it has no quota of its own. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "email-finds",
      "description": "Canonical email finds (DEV-5218): find one person's email by name and company, for any country, through Kenso's email\nchain. Dark behind the `email_finder` flag (404 when off). The Accounts lane's finds stay on\n`POST /v1/people/email-finds`; these routes never read them."
    },
    {
      "name": "event-occurrences",
      "description": "The MCP event log, poll mode (DEV-4030, SEP-3415 `events/poll`). Served only when `Ken-Version: 1.1`; the\nworkspace comes from `X-Ken-Workspace-Id`. Any member polls; each event group also needs its page (Inbox for\nreplies, Meetings for meetings, ...). `GET /v1/events`, the webhook event feed, is a different resource."
    },
    {
      "name": "event-subscriptions",
      "description": "MCP event webhook subscriptions (DEV-4030, SEP-3415 `events/subscribe` and `events/unsubscribe`). Served\nonly when `Ken-Version: 1.1`; the workspace comes from `X-Ken-Workspace-Id`. A subscription belongs to\nthe member who made it: every route reads and changes only the caller's own. Ids are `sub_` strings. Reads\ntake any member; the writes take the integrations feature, as webhook endpoints do (they POST to a caller-chosen URL)."
    },
    {
      "name": "events",
      "description": "Canonical events. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "external-bookings",
      "description": "Canonical third-party bookings (DEV-5366, epic DEV-2016): bookings prospects made through members' Cal.com, Calendly,\nHubSpot Meetings or Chili Piper pages that Kenso matched to the workspace (public.external_bookings). Read-only: Kenso\nnever owns these bookings, so there is no no-show, cancel or reassign route. Behind the meetings flag, as the recorder\nthat writes them. Visible as GET /v1/bookings shows Kenso's own: a member sees the bookings they host and the bookings\nwith an account (under account scope own, only accounts they own)."
    },
    {
      "name": "funding-rounds",
      "description": "Canonical funding rounds: companies that raised money, with the round amounts and the people named\non them. Served only when `Ken-Version: 1.1`. The data set is global: the workspace header\nadmits the caller and scopes the export allowance. Request and response bodies are passed through\nverbatim. Search, get and resolve never use the export allowance."
    },
    {
      "name": "image-variables",
      "description": "A campaign's image variables (DEV-6700): the `{{key}}` image tokens of its sequence, each a shared image or one\nimage per lead. Served only with `Ken-Version: 1.1` and the `campaign_images` workspace flag (404 while it\nis off). Reads need the Campaigns page, writes Campaigns edit. A campaign outside the workspace is 404. Every price is\ncredits, never millicredits."
    },
    {
      "name": "inbound-webhooks",
      "description": "Canonical inbound webhooks nested under a campaign. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "inbox-imports",
      "description": "Canonical inbox imports (DEV-2028). Served only when `Ken-Version: 1.1`, and only while the\n`inbox_csv_import` flag is on for the caller (404 `not_found` otherwise; off by default).\nReturns the import as an `inbox_import` job; poll `GET /v1/jobs/{jobId}?type=inbox_import`."
    },
    {
      "name": "inboxes",
      "description": "Canonical Gmail and Microsoft connect sessions (DEV-1652). Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`. Replaces the legacy\n`/v1/inbox-connections/oauth/{google|microsoft}/setup` and `/authorize` routes. The one action is\n`[WorkspaceMember]` so a client seat can connect its own primary inbox (DEV-1811)."
    },
    {
      "name": "infra",
      "description": "A workspace's infra findings (DEV-6197): billing leaks, idle and expiring domains, disconnected inboxes and the rest,\nfound by the sweep every 6 hours. `Ken-Version: 1.1` only, in the `X-Ken-Workspace-Id` workspace, behind the\n`infra_findings` flag (404 while it is off). Read, plus snooze, ignore and reopen (DEV-6199); fixes are the bulk\nactions. The staff-only kinds (renewal_shortfall, registrar_orphan) are never listed or changed here; staff use\n`/v1/admin/infra`."
    },
    {
      "name": "job-post-searches",
      "description": "Canonical Job Posts campaign action (DEV-1089 phase 3). Step 1 resolves the companies hiring for\nthe ken-jobs `jobFilters`; step 2 searches, counts and imports people at those companies through\nken-search with `peopleFilters`. Served only when `Ken-Version: 1.1`. The workspace header\nadmits the caller and scopes the import. ken-search calls carry the backend user as identity headers on the\nservice token, so ken-search applies its workspace and technology-filter checks to that user."
    },
    {
      "name": "job-postings",
      "description": "Canonical job postings from the ken-jobs index of public ATS and job-board feeds. Served only when\n`Ken-Version: 1.1`. The index is global: the workspace header admits the caller and scopes the\nexport allowance, and is not forwarded upstream. Request and response bodies are the ken-jobs\nvocabulary, passed through verbatim. Search, get and resolve never touch the export allowance."
    },
    {
      "name": "jobs",
      "description": "Canonical jobs facade. Served only when `Ken-Version: 1.1`.\nNumeric ids are unique only within `type`, so list, get, and cancel require `type`.\nContact import reads `import_run`. Contact export, lead scoring, enrichment, and scraping read the shared cache.\nDomain health reads `domain_health_runs`. Inbox import reads the shared cache and adds `inboxImport`.\nCrawl and batch scrape can be canceled. Extraction cannot."
    },
    {
      "name": "linkedin-accounts",
      "description": "Canonical LinkedIn accounts. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`. Every action needs Delivery (view to read, edit to\nchange) except the connect session, which is `[WorkspaceMember]` so a client seat can connect its own\nLinkedIn (DEV-1811)."
    },
    {
      "name": "lists",
      "description": "Canonical campaign lists. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "markets",
      "description": "Canonical market packs (DEV-15): the language facts Kenso writes each locale with, and the cold email notes of the\ncountries each pack writes for. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "me",
      "description": "Canonical caller resource. Served only when `Ken-Version: 1.1`.\nSelf-service writes stay open to every workspace role, matching the legacy\nactions they replace. No template can grant or limit them, so a key held to a permission template is refused\non every write (`[DenyScopedApiKey]`, DEV-2589): it cannot delete, edit or silence its owner's account."
    },
    {
      "name": "meeting-types",
      "description": "Canonical meeting types (DEV-1959): members' bookable meeting types, behind the scheduler flag. Any member who can see\nthe Calendar page reads every type and manages their own; admins (members feature) manage anyone's. Team types\n(round_robin, collective) are written by admins on a paid plan and carry hosts (DEV-1963)."
    },
    {
      "name": "meetings",
      "description": "A meeting's prep brief for client-facing callers (DEV-5204): the brief and its state without the credit state, the write and\nrefresh state and the model (Ken.Scraper.API.Canonical.MeetingClientBriefModel). Visible exactly when the meeting is\n(GET /v1/meetings/{meetingId}); anything else is 404. Read only: it never writes or charges. GET\n/v1/meetings/{meetingId}/brief needs the same Meetings view and answers a client seat with this same projection."
    },
    {
      "name": "members",
      "description": "Canonical workspace members. Served only when `Ken-Version: 1.1`.\n`memberId` is the Kenso user id. The workspace comes from `X-Ken-Workspace-Id`.\nAny member reads the list; changing members needs the `members` permission (DEV-1654).\nIn Kenso's demo workspace a caller who is not staff sees no staff: the list leaves them out and every by-id route is\n`404 not_found` for one, before any write (MAR-6)."
    },
    {
      "name": "outbound-site",
      "description": "Outbound domain pages (DEV-1095): the rebuilt home page a workspace's outbound domains serve, its editable fields,\nRefresh, the version history, Restore and a per-domain preview link. `Ken-Version: 1.1`, public tier, behind the\n`domain_pages` feature flag (404 when it is off). Every field or version change rewrites the workspace's\n`site.json`, which the edge reads."
    },
    {
      "name": "people",
      "description": "Canonical people: one real person in the workspace across both lanes. Kenso Search records stay\nunder `/v1/search/people`. People are created on an account through `stakeholders.create`,\nor on no account through `people.create` and `people.batch`."
    },
    {
      "name": "permission-templates",
      "description": "Canonical permission templates (DEV-1654). Served only when `Ken-Version: 1.1`; the workspace comes from\n`X-Ken-Workspace-Id`. Every action is behind the `permissions` feature flag (404 while it is off).\nAny member reads templates (public exposure); creating, editing and deleting them needs the `members`\npermission (the class's internal tier). A key held to a permission template never writes templates\n(`[DenyScopedApiKey]`, DEV-2589): it could otherwise widen the template it is held to and escape its scope."
    },
    {
      "name": "placement-tests",
      "description": "Canonical placement tests. Served only when `Ken-Version: 1.1`.\nReplaces `/v1/email-orchestrator/campaign-placement-test` and\n`/v1/email-orchestrator/campaign-placement-tests`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "prompt-versions",
      "description": "Canonical prompt versions. Served only when `Ken-Version: 1.1`.\nRestore keeps qualification workflow sync inside the existing revert command."
    },
    {
      "name": "prompts",
      "description": "Canonical prompts. Served only when `Ken-Version: 1.1`.\nQualification, scoring, and segmentation writes still sync their workflows through the existing commands."
    },
    {
      "name": "reply-templates",
      "description": "Canonical reply templates. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`. Bodies keep raw `{tokens}`."
    },
    {
      "name": "saved-list-invites",
      "description": "Saved-list invites by token (DEV-4391). Any signed-in person holding the link reads what was shared, with no workspace\nheader (a new user may have no workspace yet). Accepting puts the list in the `X-Ken-Workspace-Id` workspace and\nneeds Search edit access there and the invited email address. Behind the `saved_lists` flag; public tier since\nthe go-live (DEV-5640)."
    },
    {
      "name": "saved-lists",
      "description": "Canonical saved-list members (DEV-4391, task 08): a filtered, keyset-paged member list that never returns an email or a\nphone (`emailCount` and `phoneCount` only), and removing one member from an own list. A list is readable when\nit is the workspace's own (a private one only by its owner), shared with it through an accepted grant, or an approved\nlibrary list; anything else is 404. Saved lists sit with Search, as saved searches do: reads need the Search page\n(view), the remove needs it at edit. Behind the `saved_lists` flag; public tier since the go-live (DEV-5640)."
    },
    {
      "name": "saved-searches",
      "description": "Canonical saved searches, stored by Kenso Search. Served only when `Ken-Version: 1.1`. Every call acts for\nthe backend user in the resolved workspace (identity headers on the service token). ken-search decides who\ncan see, edit and share each saved search, so its 403 and 404 pass through."
    },
    {
      "name": "scheduled-messages",
      "description": "Canonical scheduled messages. Served only when `Ken-Version: 1.1`.\nReplaces inbox scheduled-send cancel. The workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "scraping",
      "description": "Canonical scraping. Served only when `Ken-Version: 1.1`.\nScrape, map, and search keep their paths and finish in the request.\nCrawl, extraction, and batch scrape creates return a job. Poll and cancel those jobs\nwith `GET /v1/jobs/{jobId}` and `POST /v1/jobs/{jobId}/cancel`.\nEvery response that reached a source sets `X-Ken-Web-Source` (`archive`, `workspace_key`,\n`ken_key`). With web scraping off, a request the archive cannot serve is `503 service_unavailable`\nwith the detail code `provider_unavailable`. A Firecrawl rate limit is `429 rate_limited`.\nA crawl needs a `limit` and a batch scrape or extraction its `urls`, 1 to 1,000 each; on Kenso's key the most\na job can cost is held when it starts and settled when a status read sees it finish."
    },
    {
      "name": "search",
      "description": "Canonical Kenso Search. Served only when `Ken-Version: 1.1`.\nPeople and companies are read from the global index. The workspace header admits the caller\nand is not forwarded upstream. `accounts` is named `companies` here. Every call goes to\nken-search on the backend's service token; these routes act for no particular user.\nEach profile a people or company search page, a get-by-id or a lookup hands back counts one row of the workspace's\n`searchBrowseRows` quota (DEV-3685); past it, 429 `quota_exceeded` with `Retry-After`.\nEvery person the people routes hand back (search, get, lookup, company people) carries `hasKenEmail`\n(DEV-5490, Ken.Scraper.API.Canonical.SearchKenEmailFlags) and `kenEmailStatus` (DEV-6935)."
    },
    {
      "name": "segments",
      "description": "Canonical segments nested under a campaign for list and create.\nServed only when `Ken-Version: 1.1`."
    },
    {
      "name": "sending-capacity",
      "description": "Canonical sending capacity. Served only when `Ken-Version: 1.1`.\nReplaces domain checkout capacity and domain-import capacity.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "sequences",
      "description": "Canonical email and LinkedIn sequences. Served only when `Ken-Version: 1.1`.\nA sequence is a singleton on a campaign or on a segment."
    },
    {
      "name": "shares",
      "description": "Canonical share links (DEV-1765): named, expiring review links that show a client the campaign's lead\nlists, copy, settings, ICP, weekly report or account plans. Each shared item is an external approval\nitem; on an Approve share, copy and lead lists are the launch gate's own items, so a decision on the\nlink also satisfies the gate. Reads need the Share page; every write needs Share page edit and the\n`share` feature (\"Share for approval\"). A share's `url` carries its token, the only credential\nthe public decision routes ask for, so reads return it only to members who may manage shares (DEV-2626)."
    },
    {
      "name": "signals",
      "description": "Canonical signal intake. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id` and is the only `client_id` written."
    },
    {
      "name": "tags",
      "description": "Canonical tags. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "threads",
      "description": "Workspace-wide thread actions: sidebar counts and mark-all-read (DEV-1751). Served only when\n`Ken-Version: 1.1`. The workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "tracking-links",
      "description": "Canonical tracking links nested under a campaign. Served only when `Ken-Version: 1.1`."
    },
    {
      "name": "translations",
      "description": "Translates plain text into one language (DEV-1708). Served only when `Ken-Version: 1.1`, and dark behind the\n`multilingual_outreach` workspace flag (404 while it is off)."
    },
    {
      "name": "trigger-firings",
      "description": "Canonical triggers. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "trigger-schemas",
      "description": "Canonical triggers. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "triggers",
      "description": "Canonical triggers. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`."
    },
    {
      "name": "webhook-endpoints",
      "description": "Canonical outbound webhook endpoints. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`. Endpoint ids are Svix `ep_` strings."
    },
    {
      "name": "webhook-event-types",
      "description": "Canonical outbound webhook endpoints. Served only when `Ken-Version: 1.1`.\nThe workspace comes from `X-Ken-Workspace-Id`. Endpoint ids are Svix `ep_` strings."
    },
    {
      "name": "workspaces",
      "description": "Canonical workspace resource. Served only when `Ken-Version: 1.1`.\nThe workspace id is in the path. A caller who is not a member receives 403,\nincluding super admins. Staff cross-workspace access stays on `/v1/admin`."
    }
  ]
}