{
  "openapi": "3.1.0",
  "info": {
    "title": "Fuse Business API",
    "version": "1.0.0",
    "description": "External API for lists, campaigns, prospect search and contacts. Authenticate with your API token as HTTP Basic. All paths are under /api/v1."
  },
  "servers": [
    {
      "url": "https://api.tryfuse.ai/api/v1",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "Lists"
    },
    {
      "name": "Custom columns"
    },
    {
      "name": "Smart columns"
    },
    {
      "name": "Exports"
    },
    {
      "name": "Campaigns"
    },
    {
      "name": "Knowledge hubs"
    },
    {
      "name": "Analytics"
    },
    {
      "name": "Website intent"
    },
    {
      "name": "Account"
    },
    {
      "name": "Prospect search"
    },
    {
      "name": "Campaign steps"
    },
    {
      "name": "Scheduled sends"
    },
    {
      "name": "Campaign templates"
    },
    {
      "name": "Agents"
    },
    {
      "name": "Research"
    },
    {
      "name": "Company search"
    },
    {
      "name": "Saved searches"
    },
    {
      "name": "Folders"
    },
    {
      "name": "Contacts"
    }
  ],
  "security": [
    {
      "basicAuth": []
    }
  ],
  "paths": {
    "/business/lists": {
      "get": {
        "operationId": "listLists",
        "summary": "List the token owner's prospect lists",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size: how many lists to return per page (1-1000, default 50).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 50,
              "description": "Page size: how many lists to return per page (1-1000, default 50)."
            }
          },
          {
            "name": "pageNum",
            "in": "query",
            "required": false,
            "description": "1-based page number (default 1); lists are ordered newest-created first.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based page number (default 1); lists are ordered newest-created first."
            }
          },
          {
            "name": "entityType",
            "in": "query",
            "required": false,
            "description": "Restrict to one list kind: contactList (people) or companyList (companies); omit for both.",
            "schema": {
              "type": "string",
              "enum": [
                "contactList",
                "companyList"
              ],
              "description": "Restrict to one list kind: contactList (people) or companyList (companies); omit for both."
            }
          },
          {
            "name": "folderId",
            "in": "query",
            "required": false,
            "description": "Only lists inside this folder (24-character hex folder id from GET /business/folders).",
            "schema": {
              "type": "string",
              "description": "Only lists inside this folder (24-character hex folder id from GET /business/folders)."
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Free text (1-200 characters), matched as a case-insensitive substring of the list name; every character is literal, so * and ? are not wildcards and no other field (folder, owner, description) is searched.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "description": "Free text (1-200 characters), matched as a case-insensitive substring of the list name; every character is literal, so * and ? are not wildcards and no other field (folder, owner, description) is searched."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "pagination"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "entityType",
                          "contactsCount",
                          "companiesCount",
                          "createdAt",
                          "folderId"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "entityType": {
                            "type": "string",
                            "enum": [
                              "contactList",
                              "companyList"
                            ]
                          },
                          "contactsCount": {
                            "type": "integer"
                          },
                          "companiesCount": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "type": "string"
                          },
                          "folderId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "required": [
                        "pageNum"
                      ],
                      "properties": {
                        "pageNum": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        },
                        "totalRecords": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "68a1f20b9c41d20014b3e901",
                      "name": "Q3 Fintech CFOs",
                      "entityType": "contactList",
                      "contactsCount": 412,
                      "companiesCount": 0,
                      "createdAt": "2026-07-01T09:12:44.000Z",
                      "folderId": null
                    },
                    {
                      "id": "68a1f20b9c41d20014b3e905",
                      "name": "Travel companies",
                      "entityType": "companyList",
                      "contactsCount": 0,
                      "companiesCount": 20,
                      "createdAt": "2026-06-28T11:55:33.319Z",
                      "folderId": "68a1f9aa9c41d20014b3f101"
                    }
                  ],
                  "pagination": {
                    "pageNum": 1,
                    "totalPages": 26,
                    "totalRecords": 52
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Pages through the workspace's prospect lists, newest-created first; system-generated lists (All Enriched Contacts and the like) are never included. `entityType` restricts to contact or company lists, `folderId` to one folder, and `search` matches list names case-insensitively. Each row carries its kind, its contact/company counts, and the folder it sits in (`folderId: null` = root). Use `pageNum`/`limit` to page (`pagination.totalRecords` is the overall count).\n\nErrors:\n- `422` `VALIDATION_FAILED` — A query parameter failed validation (e.g. limit above 1000, folderId not a 24-hex id).\n- `429` `RATE_LIMITED` — The lists rate bucket (120/min, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists."
      },
      "post": {
        "operationId": "createList",
        "summary": "Create a prospect list",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "list"
                  ],
                  "properties": {
                    "list": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "entityType",
                        "contactsCount",
                        "companiesCount",
                        "folderId"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "entityType": {
                          "type": "string",
                          "enum": [
                            "contactList",
                            "companyList"
                          ]
                        },
                        "contactsCount": {
                          "type": "integer"
                        },
                        "companiesCount": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "type": "string"
                        },
                        "folderId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "list": {
                    "id": "68a1f20b9c41d20014b3e901",
                    "name": "Q3 Fintech CFOs",
                    "entityType": "contactList",
                    "contactsCount": 0,
                    "companiesCount": 0,
                    "createdAt": "2026-07-27T10:00:00.000Z",
                    "folderId": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates an empty list owned by the token holder. `name` must be unique in the workspace (409 LIST_NAME_TAKEN otherwise); `entityType` picks a contact list (default) or a company list. The new list starts at the folder root — move it with `PATCH /business/lists/{listId}`. Fill it with `POST .../members` (existing contacts), `POST .../contacts` (new raw rows), `POST /business/lists/save-to-list`, a search save-to-list, or an import.\n\nErrors:\n- `409` `LIST_NAME_TAKEN` — A list with this name already exists in the workspace.\n- `422` `VALIDATION_FAILED` — The body failed validation (missing/blank name, unknown key, entityType outside contactList|companyList).\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "List name (1-255 characters, trimmed); must be unique in the workspace or the call answers 409 LIST_NAME_TAKEN."
                  },
                  "entityType": {
                    "type": "string",
                    "enum": [
                      "contactList",
                      "companyList"
                    ],
                    "default": "contactList",
                    "description": "Kind of list to create: contactList (people, default) or companyList (companies)."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}": {
      "get": {
        "operationId": "getList",
        "summary": "Get one list's metadata",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "Set to columns to add the list's custom column definitions (id, name, type) to the response.",
            "schema": {
              "type": "string",
              "enum": [
                "columns"
              ],
              "description": "Set to columns to add the list's custom column definitions (id, name, type) to the response."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "list"
                  ],
                  "properties": {
                    "list": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "entityType",
                        "completionStatus",
                        "totalRecords",
                        "metrics"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "entityType": {
                          "type": "string",
                          "enum": [
                            "contactList",
                            "companyList"
                          ]
                        },
                        "completionStatus": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "totalRecords": {
                          "type": "integer"
                        },
                        "metrics": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "required": [
                            "totalEnriched",
                            "totalWithLinkedin",
                            "totalWithProfessionalEmail",
                            "totalWithPersonalEmail",
                            "totalWithValidPhone"
                          ],
                          "properties": {
                            "totalEnriched": {
                              "type": "integer"
                            },
                            "totalWithLinkedin": {
                              "type": "integer"
                            },
                            "totalWithProfessionalEmail": {
                              "type": "integer"
                            },
                            "totalWithPersonalEmail": {
                              "type": "integer"
                            },
                            "totalWithValidPhone": {
                              "type": "integer"
                            }
                          }
                        },
                        "columns": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "name",
                              "type"
                            ],
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "list": {
                    "id": "68a1f20b9c41d20014b3e901",
                    "name": "Q3 Fintech CFOs",
                    "entityType": "contactList",
                    "completionStatus": "complete",
                    "totalRecords": 412,
                    "metrics": {
                      "totalEnriched": 400,
                      "totalWithLinkedin": 412,
                      "totalWithProfessionalEmail": 350,
                      "totalWithPersonalEmail": 40,
                      "totalWithValidPhone": 120
                    },
                    "columns": [
                      {
                        "id": "68a1f3009c41d20014b3e9a1",
                        "name": "Lead Score",
                        "type": "string"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "One list's metadata: name, kind (`entityType`), `completionStatus` (`processing` while an import, copy, save-to-list or enrichment is still populating it, `complete` otherwise — poll this after any 202 that targets the list), the row count, and the enrichment `metrics` (rows enriched and rows carrying a LinkedIn URL, professional email, personal email or valid phone). `metrics` is null for a company list, where those counters do not apply. `?include=columns` adds the custom and smart column definitions.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — listId is not a 24-hex id, or include is not \"columns\".\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      },
      "patch": {
        "operationId": "updateList",
        "summary": "Rename a list or move it between folders",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "list"
                  ],
                  "properties": {
                    "list": {
                      "type": "object",
                      "required": [
                        "id"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "folderId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "list": {
                    "id": "68a1f20b9c41d20014b3e901",
                    "name": "Q3 fintech CFOs (US)",
                    "folderId": "68a1f9aa9c41d20014b3f101"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Renames the list and/or moves it between folders. `name` must stay unique in the workspace (409 LIST_NAME_TAKEN). `folderId` moves the list into an existing folder of its own kind — an unknown id, a folder of another workspace, or one holding the other kind of list all answer 404 FOLDER_NOT_FOUND; `folderId: null` returns it to the root; `folderName` is create-or-reuse by exact, case-insensitive name for the list's kind (mutually exclusive with folderId). A move is only reported when it actually happened: a list that is not the token owner's to move answers 404 LIST_NOT_FOUND, and moving a list into the folder it is already in is a no-op that still answers 200. The response echoes only the fields that changed.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner, or the list is not theirs to move.\n- `404` `FOLDER_NOT_FOUND` — folderId does not name a folder of the token owner that holds lists of this list's kind.\n- `409` `LIST_NAME_TAKEN` — Another list already has the requested name.\n- `422` `VALIDATION_FAILED` — No field to change, both folderId and folderName sent, or a value out of bounds.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "New list name (1-255 characters, trimmed); must be unique in the workspace or the call answers 409 LIST_NAME_TAKEN."
                  },
                  "folderId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Move the list into this folder (24-character hex id of a folder of the list's own kind); null removes it from its current folder, and an unknown id answers 404 FOLDER_NOT_FOUND."
                  },
                  "folderName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Move the list into the folder with this exact name (case-insensitive, 1-120 characters), creating it for the list's kind when none exists; mutually exclusive with folderId."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteList",
        "summary": "Delete a list",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Deletes the list. The contacts themselves stay in the workspace and in every other list they belong to; custom columns and their cell values go with the list. A second delete of the same id answers 404 LIST_NOT_FOUND.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — listId is not a 24-hex id.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/lists/save-to-list": {
      "post": {
        "operationId": "copyListRows",
        "summary": "Copy rows from one list into another",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "listIds"
                  ],
                  "properties": {
                    "listIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "listIds": [
                    "68a1f20b9c41d20014b3e944"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Copies up to `limit` rows from `sourceListId` (a contact list) into a contact list named by `listId` or `listName` (create-or-reuse by exact, case-insensitive name; a name shared by two lists is 409 LIST_NAME_AMBIGUOUS, a reserved system title is 422 LIST_NAME_RESERVED). A `listId` destination that is not the token owner's answers 404 LIST_NOT_FOUND before anything is dispatched. `filters` narrows the copied rows in the same row-filter language as `GET /business/lists/{listId}/rows`. Async: 202 means the copy started and `listIds[0]` is the destination; poll `GET /business/lists/{listId}` until its `completionStatus` is `complete`. The source list is not validated up front — a bad source surfaces as a job that never fills the destination.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — The destination listId is not a list visible to the token owner.\n- `409` `LIST_NAME_TAKEN` — Creating the destination by listName collided with an existing name.\n- `409` `LIST_NAME_AMBIGUOUS` — More than one list carries listName — reference the destination by id.\n- `422` `LIST_NAME_RESERVED` — listName is a system/dynamic list title and cannot be a destination.\n- `422` `VALIDATION_FAILED` — Missing sourceListId/limit, both or neither of listId/listName, or limit outside 1-10000.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sourceListId": {
                    "type": "string",
                    "description": "24-character hex id of the contact list whose rows are copied."
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum number of rows to copy (1-10000)."
                  },
                  "filters": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact full name (contact lists). Free text: each value is matched as a case-insensitive substring of firstName + space + lastName, so Ana matches Ana Silva."
                      },
                      "title": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Job title (contact lists). Free text: each value is matched as a case-insensitive substring of the stored job title, so vp also matches VP of Sales. There is no fixed vocabulary — `GET /business/prospects/autocomplete?field=title&q=` suggests the titles the enrichment provider knows."
                      },
                      "dept": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Department (contact lists). Matched as a case-insensitive substring of the contact's department, whose values come from the provider's job_title_role vocabulary — take them from `GET /business/prospects/filter-options` (field `job_title_role`: sales, engineering, human_resources, …). A contact with several roles stores them comma-joined, which a substring match still finds. Any other text is accepted and matches only rows that literally contain it."
                      },
                      "level": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Seniority level (contact lists). Matched EXACTLY (case-insensitive, whole value) against the contact's level, whose values come from the provider's job_title_levels vocabulary — take them from `GET /business/prospects/filter-options` (field `job_title_levels`): cxo, director, entry, manager, owner, partner, senior, training, unpaid, vp. A contact carrying several levels stores them comma-joined (cxo, owner) and an exact match on one level does NOT find it; any other value is accepted and matches nothing."
                      },
                      "industryName": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's industry (contact lists). Matched EXACTLY (case-insensitive, whole value) against the industry on the contact, which the enrichment provider fills from its own 147-value list — take the values from `GET /business/prospects/filter-options` (field `industry`, e.g. computer software, hospital & health care). A near-miss such as Software is accepted and matches nothing."
                      },
                      "country": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's country (contact lists). Matched EXACTLY (case-insensitive, whole value) against the country of the contact's address, stored as the provider spells it (united states, not US) — take the values from `GET /business/prospects/filter-options` (field `location_country`). An ISO code or another spelling is accepted and matches nothing."
                      },
                      "state": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's state or region (contact lists). Matched EXACTLY (case-insensitive, whole value) against the state of the contact's address — the provider's region name, e.g. california. There is no enum; `GET /business/prospects/autocomplete?field=region&q=` suggests from the same region vocabulary. A spelling no row carries is accepted and matches nothing."
                      },
                      "personalLocation": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's location text (contact lists). Each value is matched as a case-insensitive substring against the contact's city, state AND country separately, and the row matches when any one of the three contains it — so pass ONE component (buenos aires, or california, or united states), never a whole line like san francisco, california, united states, which matches no component. No endpoint serves the city names: read the stored components off the rows themselves, where `GET /business/lists/{listId}/rows` returns each row's `location` as {city, state, country}. For the other two components, `GET /business/prospects/autocomplete?field=region&q=` suggests the state/region names and `GET /business/prospects/filter-options` (field `location_country`) lists the country names. Do NOT feed this key from `GET /business/prospects/autocomplete?field=location`: that endpoint returns whole city, state, country lines, which are exactly the shape that matches no component."
                      },
                      "companyName": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company name (both list kinds). Free text: each value is matched as a case-insensitive substring of the company name. On a company list, `GET /business/lists/{listId}/filter-values?field=name` returns the exact names that list holds."
                      },
                      "companyIndustry": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company industry (both list kinds). Matched as a case-insensitive substring of the company's industry, filled by the enrichment provider from its own list — take the values from `GET /business/prospects/filter-options` (field `job_company_industry`). Do not use the company-search vocabulary from /business/companies/filter-options: that is a different provider's list and its values are not what these rows store."
                      },
                      "companyHeadQuartersCountry": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company headquarters country (both list kinds). Matched EXACTLY (case-insensitive, whole value), but each value is first expanded to every spelling of that country (full name, ISO-3166 alpha-2 and alpha-3), because the field mixes both vocabularies — so the full country name alone is enough. Take the names from `GET /business/prospects/filter-options` (field `location_country`); a value that resolves to no country is matched verbatim."
                      },
                      "companyLocation": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company location text (contact lists). Each value is matched as a case-insensitive substring against the company address's city, state AND country separately, and the row matches when any one of the three contains it, so pass ONE component. Many companies are stored with a country and nothing else, in which case a city or state value is accepted and matches nothing; `GET /business/prospects/filter-options` (field `location_country`) lists the country names."
                      },
                      "website": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company web domain (both list kinds). Matched EXACTLY (case-insensitive, whole value) against the stored domain, so pass the BARE domain — brightpay.com. A full URL (https://brightpay.com/), a www. prefix or a partial domain is accepted and matches nothing. On a company list, `GET /business/lists/{listId}/filter-values?field=domain` returns the exact domains that list holds."
                      },
                      "numberOfEmployees": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                {
                                  "type": "number"
                                }
                              ]
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted range labels, OR-joined: a row matches when any one of them matches (at most 200)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to keep, OR-joined: a row matches when any one of them matches (at most 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to drop: a row is dropped when it matches any one of them (at most 200)."
                              }
                            }
                          }
                        ],
                        "description": "Company size (both list kinds). Each value is parsed as a headcount range and matched against the company's LinkedIn head count; accepted values are a range (\"51-200\"), an open top end (\"10001+\") or a bare head count (\"500\", meaning exactly 500). Send every value as a JSON STRING: an unquoted JSON number passes validation and then throws while the range is parsed, so the call answers 500 UNEXPECTED_ERROR instead of filtering. The provider's own labels — 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+, served by `GET /business/prospects/filter-options` (field `job_company_size`) — all parse. Anything else is read with parseInt, so a value that STARTS with digits silently narrows to that one number (\"51 to 200\" matches companies with exactly 51 employees, it is not ignored) and a value that does not (\"Enterprise\") is silently dropped; if every value is dropped nothing is left to match and the call answers zero rows rather than ignoring the filter, and companies with no stored head count never match."
                      },
                      "revenue": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                {
                                  "type": "number"
                                }
                              ]
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted range labels, OR-joined: a row matches when any one of them matches (at most 200)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to keep, OR-joined: a row matches when any one of them matches (at most 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to drop: a row is dropped when it matches any one of them (at most 200)."
                              }
                            }
                          }
                        ],
                        "description": "Company revenue (contact lists). Accepted values: a plain number, matched for exact equality against the company's stored revenue. The enrichment provider stores revenue as a LABEL (for example $10m-$25m), and a label is coerced to a number before matching, so a label — or any other non-numeric value — is accepted and matches nothing. Use numberOfEmployees to narrow by company size instead."
                      },
                      "keywords": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500,
                        "description": "Wildcard search over the contact's job title only (contact lists) — it matches no other field. Free text: every character is matched literally except the two wildcards, `*` for any run of characters and `?` for any single one, the match is case-insensitive and unanchored (vp matches VP of Sales), and the regex characters . ^ $ + ( ) [ ] { } | \\ are rejected with 422."
                      },
                      "linkedinUrl": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500,
                        "description": "LinkedIn URL (contact lists). One value, matched as a case-insensitive substring of the stored URL, which is kept scheme-less and www-less as linkedin.com/in/<slug> — so pass the slug or linkedin.com/in/<slug>. A full https://www.linkedin.com/in/<slug> is longer than the stored value, so it is accepted and matches nothing."
                      },
                      "enrichedEmail": {
                        "type": "object",
                        "properties": {
                          "include": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched",
                                "no_emails_found"
                              ]
                            },
                            "description": "Statuses to keep: enriched, not_enriched, no_emails_found. A contact is kept when it is in any one of the listed states (OR-joined), so listing every state keeps every row."
                          },
                          "exclude": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched",
                                "no_emails_found"
                              ]
                            },
                            "description": "Statuses to drop: enriched, not_enriched, no_emails_found. The states are OR-joined: a contact in any one of them is dropped."
                          }
                        },
                        "description": "Email enrichment state (contact lists). One of exactly: enriched (an email was found), not_enriched (never attempted) or no_emails_found (attempted, nothing found)."
                      },
                      "enrichedPhone": {
                        "type": "object",
                        "properties": {
                          "include": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched"
                              ]
                            },
                            "description": "Statuses to keep: enriched, not_enriched. A contact is kept when it is in any one of the listed states (OR-joined), so listing both states keeps every row."
                          },
                          "exclude": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched"
                              ]
                            },
                            "description": "Statuses to drop: enriched, not_enriched. The states are OR-joined: a contact in any one of them is dropped."
                          }
                        },
                        "description": "Phone enrichment state (contact lists). One of exactly: enriched (a phone was found) or not_enriched (no phone yet)."
                      },
                      "emailValidity": {
                        "type": "object",
                        "properties": {
                          "include": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "valid",
                                "invalid",
                                "catch-all",
                                "unknown",
                                "do_not_mail",
                                "personal",
                                "unverified"
                              ]
                            },
                            "description": "Statuses to keep: valid, invalid, catch-all, unknown, do_not_mail, personal, unverified. OR-joined over statuses and over the contact's addresses: a contact is kept when any one of its emails carries any one of the listed statuses."
                          },
                          "exclude": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "valid",
                                "invalid",
                                "catch-all",
                                "unknown",
                                "do_not_mail",
                                "personal",
                                "unverified"
                              ]
                            },
                            "description": "Statuses to drop: valid, invalid, catch-all, unknown, do_not_mail, personal, unverified. OR-joined over statuses and over the contact's addresses: a contact is dropped when any one of its emails carries any one of the listed statuses."
                          }
                        },
                        "description": "Validation status of the contact's emails (contact lists). One of exactly: valid, invalid, catch-all, unknown, do_not_mail, personal, unverified — valid means a deliverable WORK address (personal ones are excluded from it), personal means a deliverable personal address, and unverified means a user-uploaded address that was never verified."
                      },
                      "icpMatch": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            },
                            "minItems": 1,
                            "description": "Accepted values: exactly one of [\"yes\"] (ICP-matched rows) or [\"no\"] (the rest); [\"yes\",\"no\"] is read as [\"yes\"]."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              }
                            }
                          }
                        ],
                        "description": "ICP match outcome (contact lists). Accepted values: exactly one of yes (rows matching the ICP saved in the app) or no (the rest). When the workspace has no ICP configured nothing is a match, so yes returns no rows at all and no returns every row."
                      },
                      "campaignEngagement": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Campaign engagement bucket (both list kinds). One of exactly: contacted (at least one campaign email has been sent to the contact), in_active_campaign (targeted by a running campaign, nothing sent yet) or never_engaged (neither) — compared as whole values, case included, so any other value is accepted and returns no rows. A company's bucket is the highest bucket among its contacts."
                      },
                      "otherLists": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "NAMES (not ids) of other lists the contact must — or with exclude, must not — also belong to (contact lists). Each value is matched as a case-insensitive substring of the list names from `GET /business/lists`; only the team's static contact lists are searched, so the list being read, dynamic lists and archived lists never satisfy it."
                      },
                      "customColumns": {
                        "type": "object",
                        "properties": {},
                        "description": "Cell filters keyed by custom/smart column id (from `GET /business/lists/{listId}/columns`), both list kinds. Every column listed must match (AND-ed); a column id that is not on this list matches no row."
                      }
                    },
                    "description": "Optional row-filter object narrowing which source rows are copied, in the same language as the filters query of GET /business/lists/{listId}/rows. Text keys (name, title, dept, level, industryName, country, state, personalLocation, companyName, companyIndustry, companyHeadQuartersCountry, companyLocation, website, campaignEngagement, otherLists) take an array of accepted values, e.g. {\"companyName\":[\"pomelo\"]} or {\"country\":[\"argentina\"]}, or {\"include\":[...],\"exclude\":[...]} — otherLists takes list NAMES, not ids; numberOfEmployees takes headcount ranges the same way but as STRINGS (\"51-200\", \"10001+\" or a bare head count \"500\" — an unquoted JSON number answers 500) and revenue a plain number; keywords (a wildcard match on the job title only) and linkedinUrl take one string; enrichedEmail, enrichedPhone and emailValidity take {\"include\":[...]} of their statuses; icpMatch takes [\"yes\"] or [\"no\"]; customColumns maps a column id to {\"dataType\":\"string\",\"include\":[...]}, {\"dataType\":\"boolean\",\"value\":true} or {\"dataType\":\"number\",\"rangeMin\":1,\"rangeMax\":10}. Company lists honour companyName, companyIndustry, companyHeadQuartersCountry, website, numberOfEmployees, campaignEngagement and customColumns. Every key is optional; an unknown key or a wrong value shape is rejected rather than ignored. Values inside one key are OR-joined and different keys are AND-ed. VALUES ARE NOT VALIDATED: level, industryName, country, state, website and companyHeadQuartersCountry are matched as whole values and campaignEngagement, icpMatch and enum cells as exact strings, so a value in the wrong vocabulary is accepted and silently matches nothing — each key's own description names its vocabulary and the endpoint that serves it. A rejected filter answers 422 VALIDATION_FAILED."
                  },
                  "listId": {
                    "type": "string",
                    "description": "24-character hex id of an existing contact list to copy into; mutually exclusive with listName."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Name of the destination contact list (1-255 characters): an existing list with this exact name (case-insensitive) is reused, otherwise it is created; two lists sharing the name answer 409 LIST_NAME_AMBIGUOUS and reserved system titles answer 422 LIST_NAME_RESERVED."
                  }
                },
                "required": [
                  "sourceListId",
                  "limit"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/derive-company-list": {
      "post": {
        "operationId": "deriveCompanyList",
        "summary": "Build a company list from a contact list's companies",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "list",
                    "sourceContacts"
                  ],
                  "properties": {
                    "list": {
                      "type": "object",
                      "required": [
                        "id",
                        "name"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    },
                    "sourceContacts": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    }
                  }
                },
                "example": {
                  "list": {
                    "id": "68a1f20b9c41d20014b3e977",
                    "name": "Q3 fintech companies"
                  },
                  "sourceContacts": 412
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Builds a new company list from the companies the contact list's rows belong to. Async: 202 returns the created list (in `processing` state) and `sourceContacts`, the number of contacts examined; poll `GET /business/lists/{listId}` on the new id until `completionStatus` is `complete`. A source list still being built answers 409 LIST_PROCESSING — retry once its own `completionStatus` leaves `processing`.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No source list with that id is visible to the token owner.\n- `409` `LIST_NAME_TAKEN` — A list already carries the requested name.\n- `409` `LIST_PROCESSING` — The source list is still being built; retry once its completionStatus leaves processing.\n- `422` `CONTACT_LIST_REQUIRED` — The source list is a company list; companies are derived from a contact list's rows.\n- `422` `LIST_EMPTY` — The source list has no contacts to derive companies from.\n- `422` `INVALID_REQUEST` — CRM rejected the request for a reason outside the mapped set.\n- `422` `VALIDATION_FAILED` — name missing/blank or over 255 characters, or an unknown body key.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Name for the new company list (1-255 characters); a name already in use answers 409 LIST_NAME_TAKEN."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/filter-values": {
      "get": {
        "operationId": "getListFilterValues",
        "summary": "Distinct values a company list carries for a field",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          },
          {
            "name": "field",
            "in": "query",
            "required": true,
            "description": "Which company field to collect distinct values for: name (company names, the vocabulary of the companyName row filter) or domain (company web domains, the vocabulary of the website row filter). Values come from the COMPANY rows of the list, so a contact list answers with an empty array.",
            "schema": {
              "type": "string",
              "enum": [
                "name",
                "domain"
              ],
              "description": "Which company field to collect distinct values for: name (company names, the vocabulary of the companyName row filter) or domain (company web domains, the vocabulary of the website row filter). Values come from the COMPANY rows of the list, so a contact list answers with an empty array."
            }
          },
          {
            "name": "start",
            "in": "query",
            "required": false,
            "description": "1-based row of the list to start from, in the list's display order (default 1). Rows, not distinct values.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based row of the list to start from, in the list's display order (default 1). Rows, not distinct values."
            }
          },
          {
            "name": "amount",
            "in": "query",
            "required": false,
            "description": "Rows to read from start, 1-1000 (default 1000). The answer holds at most this many values; page with start to read a longer list.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 1000,
              "description": "Rows to read from start, 1-1000 (default 1000). The answer holds at most this many values; page with start to read a longer list."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "field",
                    "values",
                    "total"
                  ],
                  "properties": {
                    "field": {
                      "type": "string",
                      "enum": [
                        "name",
                        "domain"
                      ]
                    },
                    "values": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Company rows on the list — the unit `start` and `amount` count in."
                    }
                  }
                },
                "example": {
                  "field": "domain",
                  "values": [
                    "brightpay.com",
                    "stripe.com"
                  ],
                  "total": 2
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The distinct values a company list carries for one company field — `name` (company names) or `domain` (web domains) — over one window of its rows, for building row filters or exclusion sets. `start` (1-based) and `amount` (max 1000, the default) select rows in the list's display order; `values` is the flat, de-duplicated array those rows carry and `total` the list's row count, so a longer list is read by paging `start`. A contact list answers an empty array.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — field missing or not name|domain.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/lists/{listId}/rows": {
      "get": {
        "operationId": "listListRows",
        "summary": "List a list's contacts (with ids and column values)",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size: how many rows to return per page (1-1000, default 100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100,
              "description": "Page size: how many rows to return per page (1-1000, default 100)."
            }
          },
          {
            "name": "pageNum",
            "in": "query",
            "required": false,
            "description": "1-based page number (default 1).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based page number (default 1)."
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Field to sort rows by; it is IGNORED unless sortOrder is sent with it. Contact lists: any field on the contact record — the index-backed and therefore fast ones are firstName, lastName, jobTitle, createdAt, address.city and address.country (updatedAt carries NO index on the contact collection, so it is accepted but sorts as a blocking in-memory sort); a company field prefixed with company., where the accepted values are exactly company.name, company.domain, company.industry, company.country, company.type, company.revenue, company.linkedInHeadCount, company.address.city, company.address.state and company.address.country; or customColumns_<columnId> for a custom/smart column. Company lists: a company field by its own name (name, domain, industry, revenue, linkedInHeadCount) or customColumns_<columnId>. An unrecognised key is accepted and falls back to the list's default order rather than erroring.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "description": "Field to sort rows by; it is IGNORED unless sortOrder is sent with it. Contact lists: any field on the contact record — the index-backed and therefore fast ones are firstName, lastName, jobTitle, createdAt, address.city and address.country (updatedAt carries NO index on the contact collection, so it is accepted but sorts as a blocking in-memory sort); a company field prefixed with company., where the accepted values are exactly company.name, company.domain, company.industry, company.country, company.type, company.revenue, company.linkedInHeadCount, company.address.city, company.address.state and company.address.country; or customColumns_<columnId> for a custom/smart column. Company lists: a company field by its own name (name, domain, industry, revenue, linkedInHeadCount) or customColumns_<columnId>. An unrecognised key is accepted and falls back to the list's default order rather than erroring."
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction: asc (ascending) or desc (descending). Required for sortBy to take effect — without it the rows keep their default order.",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "description": "Sort direction: asc (ascending) or desc (descending). Required for sortBy to take effect — without it the rows keep their default order."
            }
          },
          {
            "name": "filters",
            "in": "query",
            "required": false,
            "description": "URL-encoded JSON object (max 8000 characters) narrowing which rows are returned, e.g. {\"companyName\":[\"pomelo\"]} or {\"country\":[\"argentina\"]}. Text keys (name, title, dept, level, industryName, country, state, personalLocation, companyName, companyIndustry, companyHeadQuartersCountry, companyLocation, website, campaignEngagement, otherLists) take an array of accepted values, e.g. {\"companyName\":[\"pomelo\"]} or {\"country\":[\"argentina\"]}, or {\"include\":[...],\"exclude\":[...]} — otherLists takes list NAMES, not ids; numberOfEmployees takes headcount ranges the same way but as STRINGS (\"51-200\", \"10001+\" or a bare head count \"500\" — an unquoted JSON number answers 500) and revenue a plain number; keywords (a wildcard match on the job title only) and linkedinUrl take one string; enrichedEmail, enrichedPhone and emailValidity take {\"include\":[...]} of their statuses; icpMatch takes [\"yes\"] or [\"no\"]; customColumns maps a column id to {\"dataType\":\"string\",\"include\":[...]}, {\"dataType\":\"boolean\",\"value\":true} or {\"dataType\":\"number\",\"rangeMin\":1,\"rangeMax\":10}. Company lists honour companyName, companyIndustry, companyHeadQuartersCountry, website, numberOfEmployees, campaignEngagement and customColumns. Every key is optional; an unknown key or a wrong value shape is rejected rather than ignored. Values inside one key are OR-joined and different keys are AND-ed. VALUES ARE NOT VALIDATED: level, industryName, country, state, website and companyHeadQuartersCountry are matched as whole values and campaignEngagement, icpMatch and enum cells as exact strings, so a value in the wrong vocabulary is accepted and silently matches nothing — each key's own description names its vocabulary and the endpoint that serves it. Malformed JSON, an unknown key or a wrong value shape answers 422 INVALID_ROW_FILTERS.",
            "schema": {
              "type": "string",
              "maxLength": 8000,
              "description": "URL-encoded JSON object (max 8000 characters) narrowing which rows are returned, e.g. {\"companyName\":[\"pomelo\"]} or {\"country\":[\"argentina\"]}. Text keys (name, title, dept, level, industryName, country, state, personalLocation, companyName, companyIndustry, companyHeadQuartersCountry, companyLocation, website, campaignEngagement, otherLists) take an array of accepted values, e.g. {\"companyName\":[\"pomelo\"]} or {\"country\":[\"argentina\"]}, or {\"include\":[...],\"exclude\":[...]} — otherLists takes list NAMES, not ids; numberOfEmployees takes headcount ranges the same way but as STRINGS (\"51-200\", \"10001+\" or a bare head count \"500\" — an unquoted JSON number answers 500) and revenue a plain number; keywords (a wildcard match on the job title only) and linkedinUrl take one string; enrichedEmail, enrichedPhone and emailValidity take {\"include\":[...]} of their statuses; icpMatch takes [\"yes\"] or [\"no\"]; customColumns maps a column id to {\"dataType\":\"string\",\"include\":[...]}, {\"dataType\":\"boolean\",\"value\":true} or {\"dataType\":\"number\",\"rangeMin\":1,\"rangeMax\":10}. Company lists honour companyName, companyIndustry, companyHeadQuartersCountry, website, numberOfEmployees, campaignEngagement and customColumns. Every key is optional; an unknown key or a wrong value shape is rejected rather than ignored. Values inside one key are OR-joined and different keys are AND-ed. VALUES ARE NOT VALIDATED: level, industryName, country, state, website and companyHeadQuartersCountry are matched as whole values and campaignEngagement, icpMatch and enum cells as exact strings, so a value in the wrong vocabulary is accepted and silently matches nothing — each key's own description names its vocabulary and the endpoint that serves it. Malformed JSON, an unknown key or a wrong value shape answers 422 INVALID_ROW_FILTERS."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "entityType",
                    "data",
                    "pagination"
                  ],
                  "properties": {
                    "entityType": {
                      "type": "string",
                      "enum": [
                        "contactList",
                        "companyList"
                      ]
                    },
                    "data": {
                      "type": "array",
                      "description": "Contact rows when entityType is contactList, company rows when it is companyList.",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "firstName": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "lastName": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "linkedinUrl": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only; a full https URL."
                          },
                          "jobTitle": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "companyName": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "companyDomain": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "emails": {
                            "type": "array",
                            "description": "Contact rows only.",
                            "items": {
                              "type": "object",
                              "required": [
                                "email",
                                "status",
                                "isPersonal"
                              ],
                              "properties": {
                                "email": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "enum": [
                                    "valid",
                                    "invalid",
                                    "catch-all",
                                    "unknown",
                                    "do_not_mail",
                                    "unverified",
                                    null
                                  ]
                                },
                                "isPersonal": {
                                  "type": "boolean"
                                }
                              }
                            }
                          },
                          "phones": {
                            "type": "array",
                            "description": "Contact rows only.",
                            "items": {
                              "type": "object",
                              "required": [
                                "phoneNumber",
                                "status"
                              ],
                              "properties": {
                                "phoneNumber": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "enum": [
                                    "valid",
                                    "hq",
                                    "unverified",
                                    null
                                  ]
                                }
                              }
                            }
                          },
                          "primaryEmail": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "primaryPhone": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "icpMatch": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Contact rows only."
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Company rows only."
                          },
                          "domain": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Company rows only."
                          },
                          "industry": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Company rows only."
                          },
                          "employeeCount": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Company rows only."
                          },
                          "revenue": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Company rows only."
                          },
                          "headquartersCountry": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Company rows only; free text, not a single vocabulary — either an ISO-3166 alpha-3 code (\"NLD\") or a full lower-case country name (\"united states\"), depending on which enrichment path wrote it."
                          },
                          "engagement": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "source": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "lists": {
                            "type": "array",
                            "description": "Contact rows only.",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                }
                              }
                            }
                          },
                          "location": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "city": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "state": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "country": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            }
                          },
                          "columnValues": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "required": [
                        "pageNum"
                      ],
                      "properties": {
                        "pageNum": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        },
                        "totalRecords": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "entityType": "contactList",
                  "data": [
                    {
                      "id": "68a1f2c89c41d20014b3e955",
                      "firstName": "Ada",
                      "lastName": "Nwosu",
                      "linkedinUrl": "https://www.linkedin.com/in/ada-nwosu",
                      "jobTitle": "Chief Financial Officer",
                      "companyName": "Brightpay",
                      "companyDomain": "brightpay.com",
                      "emails": [
                        {
                          "email": "ada@brightpay.com",
                          "status": "valid",
                          "isPersonal": false
                        }
                      ],
                      "phones": [
                        {
                          "phoneNumber": "+13015023231",
                          "status": "valid"
                        }
                      ],
                      "primaryEmail": "ada@brightpay.com",
                      "primaryPhone": "+13015023231",
                      "icpMatch": true,
                      "engagement": "never_engaged",
                      "source": "prospect_search",
                      "lists": [
                        {
                          "id": "68a1f20b9c41d20014b3e901",
                          "name": "Q3 Fintech CFOs"
                        }
                      ],
                      "location": {
                        "city": "san francisco",
                        "state": "california",
                        "country": "united states"
                      },
                      "columnValues": {
                        "68a1f3009c41d20014b3e9a1": "warm"
                      }
                    },
                    {
                      "id": "68a1f2c89c41d20014b3e956",
                      "firstName": "Sam",
                      "lastName": "Rivera",
                      "linkedinUrl": null,
                      "jobTitle": null,
                      "companyName": "Brightpay",
                      "companyDomain": null,
                      "emails": [],
                      "phones": [],
                      "primaryEmail": null,
                      "primaryPhone": null,
                      "icpMatch": null,
                      "engagement": "never_engaged",
                      "source": "csv_upload",
                      "lists": [],
                      "location": null,
                      "columnValues": {}
                    }
                  ],
                  "pagination": {
                    "pageNum": 1,
                    "totalPages": 206,
                    "totalRecords": 412
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Pages through a list's rows. `entityType` says which shape `data` holds: a contact list's rows carry the contact id (the id `members`, `columns/{columnId}/values`, `enrich` and `crm-push` accept), the discovered emails and phones with their validation status, the primaries, ICP match, campaign engagement, acquisition source, the other lists the contact belongs to, its location and `columnValues` (custom and smart column cells keyed by column id); a company list's rows carry the company's own fields (name, domain, industry, employeeCount, revenue, headquartersCountry) plus engagement, source, location and `columnValues`. LinkedIn URLs come back as full https URLs. `sortBy`/`sortOrder` sort (an unrecognised sort key falls back to the list's default order). `filters` is a URL-encoded JSON object in the row-filter language: text keys take an array of accepted values or `{include, exclude}` — `{\"companyName\":[\"pomelo\"]}`, `{\"country\":[\"argentina\"]}`; `enrichedEmail`/`enrichedPhone`/`emailValidity` take `{\"include\":[...]}` of their statuses; `icpMatch` takes `[\"yes\"]` or `[\"no\"]`; `customColumns` maps a column id to `{\"dataType\":\"string\",\"include\":[...]}`. Two keys are narrower than their names suggest: `keywords` is a wildcard match on the job title alone (`*` and `?` are the only wildcards; other regex characters are rejected) and `otherLists` matches other lists by NAME, not by id. An unknown key or a wrong value shape answers 422 INVALID_ROW_FILTERS naming the offending key.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `INVALID_ROW_FILTERS` — filters is not a JSON object, carries an unknown key, a value has the wrong shape, or `keywords` carries one of the regex metacharacters . ^ $ + ( ) [ ] { } | \\ (the offending key is named in the message).\n- `422` `VALIDATION_FAILED` — limit/pageNum/sortOrder out of range, or filters longer than 8000 characters.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/lists/{listId}/members": {
      "post": {
        "operationId": "addListMembers",
        "summary": "Add existing contacts to a list (by id)",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "submittedCount",
                    "addedCount"
                  ],
                  "properties": {
                    "submittedCount": {
                      "type": "integer"
                    },
                    "addedCount": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "submittedCount": 3,
                  "addedCount": 2
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Adds existing contacts to the list by id (row ids from `GET /business/lists/{listId}/rows` on another list, or `POST /business/contacts/resolve`). Idempotent: contacts already in the list are skipped, so `addedCount` (net new members) can be lower than `submittedCount`. Up to 5,000 ids per call; no credits are spent.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — contactIds missing, empty, over 5000 entries, or containing a non-24-hex id.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contactIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "24-character hex id of a contact (the row id from GET /business/lists/{listId}/rows)."
                    },
                    "minItems": 1,
                    "maxItems": 5000,
                    "description": "Contact ids (24-character hex, 1-5000 per call) to add to or remove from the list; ids already in the list are ignored on add."
                  }
                },
                "required": [
                  "contactIds"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "removeListMembers",
        "summary": "Remove contacts from a list",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "submittedCount"
                  ],
                  "properties": {
                    "submittedCount": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "submittedCount": 2
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Removes contacts from the list by id. The contacts themselves stay in the workspace and in every other list. Idempotent (ids not in the list are ignored) and the response reports only how many ids were submitted, not how many memberships were removed. Up to 5,000 ids per call.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — contactIds missing, empty, over 5000 entries, or containing a non-24-hex id.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contactIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "24-character hex id of a contact (the row id from GET /business/lists/{listId}/rows)."
                    },
                    "minItems": 1,
                    "maxItems": 5000,
                    "description": "Contact ids (24-character hex, 1-5000 per call) to add to or remove from the list; ids already in the list are ignored on add."
                  }
                },
                "required": [
                  "contactIds"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/contacts": {
      "post": {
        "operationId": "uploadListContacts",
        "summary": "Upload new contact data into a list (RAW upload)",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "addedCount",
                    "contactIds"
                  ],
                  "properties": {
                    "addedCount": {
                      "type": "integer"
                    },
                    "contactIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "addedCount": 2,
                  "contactIds": [
                    "68a1f4109c41d20014b3ea01",
                    "68a1f4109c41d20014b3ea02"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates new contacts from the supplied data and adds them to the list, the same path a CSV upload takes (no enrichment runs and no credits are spent). Every row becomes a new contact — there is no de-duplication against contacts already in the workspace, so retrying a call duplicates rows. Emails are stored as the primary email with status `valid` without verification, phones are normalised to E.164 (US assumed when no country code is given), and LinkedIn URLs are normalised to `linkedin.com/in/<slug>` so the contact can later be found with `POST /business/contacts/resolve`. The returned `contactIds` are the new rows' ids, usable with `columns/{columnId}/values`, `enrich` and `crm-push`. Up to 500 contacts per call.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `CONTACT_LIST_REQUIRED` — The list is a company list; contact rows cannot be written into it.\n- `422` `VALIDATION_FAILED` — contacts missing/empty/over 500, a row with none of email/linkedinUrl/firstName/lastName, a malformed email, or an unknown key.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contacts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "firstName": {
                          "type": "string",
                          "maxLength": 200,
                          "description": "Given name (max 200 characters)."
                        },
                        "lastName": {
                          "type": "string",
                          "maxLength": 200,
                          "description": "Family name (max 200 characters)."
                        },
                        "email": {
                          "type": "string",
                          "format": "email",
                          "maxLength": 320,
                          "description": "Email address (max 320 characters); stored as the contact's primary email with status valid — it is not verified on upload."
                        },
                        "phone": {
                          "type": "string",
                          "maxLength": 50,
                          "description": "Phone number (max 50 characters). Free text in any dialable shape — +1 206 362 2366, (206) 362-2366, 2063622366 — it is never rejected for its format: each value is normalised to E.164, reading the country from a leading +<code> and otherwise assuming US, and a value that cannot be parsed is stored with its digits kept. A comma-separated string is split into several phones and the first becomes the primary."
                        },
                        "linkedinUrl": {
                          "type": "string",
                          "maxLength": 500,
                          "description": "LinkedIn profile URL (max 500 characters); normalised to linkedin.com/in/<slug> and used to match the contact later — a non-LinkedIn URL is dropped."
                        },
                        "jobTitle": {
                          "type": "string",
                          "maxLength": 300,
                          "description": "Job title (max 300 characters). Free text, stored verbatim: there is no vocabulary and no normalisation, and this is the only field the title and keywords row filters read — the level and dept filters stay empty for an uploaded contact until it is enriched."
                        },
                        "companyName": {
                          "type": "string",
                          "maxLength": 300,
                          "description": "Employer name (max 300 characters); matched to an existing company in the workspace by domain or name, otherwise created."
                        },
                        "companyDomain": {
                          "type": "string",
                          "maxLength": 300,
                          "description": "Employer web domain (max 300 characters), e.g. brightpay.com."
                        }
                      },
                      "description": "One contact to create; at least one of email, linkedinUrl, firstName or lastName is required."
                    },
                    "minItems": 1,
                    "maxItems": 500,
                    "description": "Contacts to create as new rows in the list, at most 500 per call. The entries do not combine: each one becomes its own new contact, in the order sent, and there is no de-duplication — against the workspace or within the call, so the same person sent twice lands twice. Every field is free text stored as given (only linkedinUrl and phone are normalised); nothing is enriched or verified on upload."
                  }
                },
                "required": [
                  "contacts"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/columns": {
      "get": {
        "operationId": "listListColumns",
        "summary": "List a list's custom column definitions",
        "tags": [
          "Custom columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "columns"
                  ],
                  "properties": {
                    "columns": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "type"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "columns": [
                    {
                      "id": "68a1f3009c41d20014b3e9a1",
                      "name": "Lead Score",
                      "type": "string"
                    },
                    {
                      "id": "68a1f3009c41d20014b3e9a2",
                      "name": "Website",
                      "type": "url"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The list's column definitions — both plain custom columns created here and smart (AI) columns — as `{ id, name, type }`. Column ids key the `columnValues` map on `GET .../rows` and are what `PATCH .../columns/{columnId}/values` and `DELETE .../columns/{columnId}` take.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — listId is not a 24-hex id.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      },
      "post": {
        "operationId": "createListColumn",
        "summary": "Create a custom column on a list",
        "tags": [
          "Custom columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "column"
                  ],
                  "properties": {
                    "column": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "type"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "string",
                            "number",
                            "date",
                            "boolean",
                            "url"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "column": {
                    "id": "68a1f3009c41d20014b3e9a1",
                    "name": "Lead Score",
                    "type": "string"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Adds a plain custom column to the list. `type` fixes what cells may hold — `string` (default), `number`, `date`, `boolean`, or `url` (a `{label, value}` link). Names are unique per list, case-insensitively (409 COLUMN_NAME_TAKEN). Write cells with `PATCH .../columns/{columnId}/values`; for an AI-computed column use `POST .../smart-columns` instead.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `409` `COLUMN_NAME_TAKEN` — A column with this name (case-insensitive) already exists on the list.\n- `422` `VALIDATION_FAILED` — name missing/blank/over 100 characters, type outside the enum, or an unknown key.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "Column name (1-100 characters); unique per list (case-insensitive) or the call answers 409 COLUMN_NAME_TAKEN."
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "string",
                      "number",
                      "date",
                      "boolean",
                      "url"
                    ],
                    "default": "string",
                    "description": "Value type the column stores: string (default), number, date, boolean or url (a {label, value} link)."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/columns/{columnId}": {
      "delete": {
        "operationId": "deleteListColumn",
        "summary": "Delete a custom column (its values go with it)",
        "tags": [
          "Custom columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          },
          {
            "name": "columnId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the custom column (from GET /business/lists/{listId}/columns).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the custom column (from GET /business/lists/{listId}/columns)."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Removes a custom or smart column from the list together with every cell value it held. The column must exist on that list (404 COLUMN_NOT_FOUND otherwise); the deletion cannot be undone.\n\nErrors:\n- `404` `COLUMN_NOT_FOUND` — No column with that id exists on the list.\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — listId or columnId is not a 24-hex id.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/lists/{listId}/smart-columns": {
      "post": {
        "operationId": "createSmartColumn",
        "summary": "Add an AI column that researches every row",
        "tags": [
          "Smart columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jobId",
                    "column"
                  ],
                  "properties": {
                    "jobId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Id of the run that was started; poll it on GET /business/lists/{listId}/smart-columns/{jobId}/status."
                    },
                    "column": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "engine"
                      ],
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Id of the new column (the columnId used by every other smart-column endpoint)."
                        },
                        "name": {
                          "type": "string",
                          "description": "The column name as sent."
                        },
                        "engine": {
                          "type": "string",
                          "enum": [
                            "standard",
                            "deep_research"
                          ],
                          "description": "The engine the column runs on."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "jobId": "68a1f6109c41d20014b3ec21",
                  "column": {
                    "id": "68a1f3009c41d20014b3e9a1",
                    "name": "Hiring signals",
                    "engine": "standard"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Adds a smart column to the list and starts its first run. Every covered row is researched from `prompt` by the chosen `engine` and billed at that engine's per-row credit rate; the run is charged up front, so the call answers 402 INSUFFICIENT_CREDITS when your balance cannot cover it and nothing is created. `runOn` bounds the first run (`first_1` … `first_1000` rows in the list's current order, or `all`) and `filters` narrows the rows it may cover; run the column again later (`POST …/smart-columns/{columnId}/rerun` with `mode: new_only`) to fill the rest. `engine: deep_research` uses the multi-provider Deep Research pipeline at a higher per-row rate and is the only engine that accepts a `providerIds` restriction (provider slugs from `GET /business/research/providers`); `standard` (default) is the per-row web-research agent. The name must be free on the list (409 COLUMN_NAME_TAKEN) and must not be a reserved built-in column name (422 COLUMN_NAME_RESERVED), and a filter that matches no row is rejected with 422 NO_ROWS_TO_RESEARCH before anything is charged. The call is asynchronous: it answers 202 with the run's `jobId` and the new column. Poll `GET /business/lists/{listId}/smart-columns/{jobId}/status` until `status` is `completed`, `partially_completed`, `failed` or `cancelled`, then read the values from `GET /business/lists/{listId}/rows` (`columnValues[columnId]`) and each cell's sources from the provenance endpoint.\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — Your credit balance cannot cover the run (covered rows × the engine's per-row rate); nothing was started or charged.\n- `404` `LIST_NOT_FOUND` — No list with that id belongs to you.\n- `409` `COLUMN_NAME_TAKEN` — A column with this name already exists on the list.\n- `422` `COLUMN_NAME_RESERVED` — The name is one of the reserved built-in column names (name, first name, last name, job title, company, email, phone …).\n- `422` `PROVIDERS_NOT_SUPPORTED` — providerIds was sent for the standard engine; only a deep_research column can be restricted to specific providers.\n- `422` `NO_ROWS_TO_RESEARCH` — No row on the list matches `filters`, so there is nothing to research and nothing was charged.\n- `422` `INVALID_REQUEST` — CRM rejected the column definition for a reason with no more specific code.\n- `422` `VALIDATION_FAILED` — The path, query or body failed validation; `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the lists bucket, which every /business/lists endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "Display name of the new column (1-100 characters, trimmed). Must be unique on the list and must not be a reserved built-in column name such as name, first name, last name, job title, company, email or phone."
                  },
                  "prompt": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "The research instruction the engine answers once per covered row (1-2000 characters, trimmed); the answer is written into that row's cell and its sources are kept as provenance."
                  },
                  "runOn": {
                    "type": "string",
                    "enum": [
                      "first_1",
                      "first_10",
                      "first_100",
                      "first_1000",
                      "all"
                    ],
                    "description": "How many rows the first run covers, taken in the list's current order after `filters`: first_1, first_10, first_100 or first_1000 take that many rows; all covers every row. Every covered row is billed at the engine's per-row credit rate up front; rerun the column later for the rest."
                  },
                  "engine": {
                    "type": "string",
                    "enum": [
                      "standard",
                      "deep_research"
                    ],
                    "default": "standard",
                    "description": "Engine that researches each row: standard (default) is the fast per-row web-research agent; deep_research is the multi-provider Deep Research pipeline, billed at a higher per-row rate, and the only engine that accepts providerIds."
                  },
                  "filters": {
                    "type": "object",
                    "properties": {},
                    "description": "Optional row filter in the same JSON row-filter language as the `filters` query of GET /business/lists/{listId}/rows (built-in fields by canonical key, custom and smart columns under customColumns keyed by column id); only matching rows are covered. Omit to cover the whole list."
                  },
                  "providerIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64,
                      "description": "A Deep Research provider id: the `id` (catalog slug, for example `zerobounce`) of an entry returned by GET /business/research/providers, not a Mongo id."
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "deep_research only: restrict the research to these provider ids, each the `id` of an entry returned by GET /business/research/providers. The ids are an allowlist, not an order: the run may call any of them, chooses per row, and need not use them all; the order you send them in is ignored. Send 1 to 50 distinct ids — an empty array or a repeated id is rejected. Ids are never checked against the catalog: a typo, a provider whose `allowedInRuns` is false, or a `byok-required` provider you have not saved a key for is accepted and then silently dropped from the run, and if none of the ids survive that check the rows are researched only by the providers Fuse always includes, so the answers come back far thinner than you asked for with no error anywhere. Sent with engine standard the call is rejected with 422 PROVIDERS_NOT_SUPPORTED. Omit to let the run use every provider available to your workspace."
                  }
                },
                "required": [
                  "name",
                  "prompt",
                  "runOn"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/smart-columns/{jobId}/status": {
      "get": {
        "operationId": "getSmartColumnJobStatus",
        "summary": "Poll a smart-column run",
        "tags": [
          "Smart columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "Id of the list that owns the smart column.",
            "schema": {
              "type": "string",
              "description": "Id of the list that owns the smart column."
            }
          },
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "Id of the smart-column run to poll, as returned in `jobId` by the create or rerun call that started it.",
            "schema": {
              "type": "string",
              "description": "Id of the smart-column run to poll, as returned in `jobId` by the create or rerun call that started it."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "job"
                  ],
                  "properties": {
                    "job": {
                      "type": "object",
                      "required": [
                        "id",
                        "status",
                        "mode",
                        "runOn",
                        "totalRows",
                        "processedRows",
                        "successfulRows",
                        "failedRows",
                        "creditsUsed",
                        "creditsPerRow",
                        "createdAt",
                        "startedAt",
                        "completedAt",
                        "cancelledAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Id of this run — the jobId create or rerun returned."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "processing",
                            "completed",
                            "failed",
                            "partially_completed",
                            "cancelled"
                          ],
                          "description": "pending and processing are in progress; completed, partially_completed (some rows failed), failed and cancelled (superseded by a newer run or a prompt edit) are terminal."
                        },
                        "mode": {
                          "type": "string",
                          "enum": [
                            "initial",
                            "all",
                            "new_only",
                            "refresh",
                            "single_row"
                          ],
                          "description": "Why the run exists: initial (column creation), all / new_only (rerun), refresh (prompt edit), single_row (automation)."
                        },
                        "runOn": {
                          "type": "string",
                          "enum": [
                            "first_1",
                            "first_10",
                            "first_100",
                            "first_1000",
                            "all"
                          ],
                          "description": "Row budget the run was started with."
                        },
                        "totalRows": {
                          "type": "integer",
                          "description": "Rows the run covers."
                        },
                        "processedRows": {
                          "type": "integer",
                          "description": "Rows finished so far (successful + failed)."
                        },
                        "successfulRows": {
                          "type": "integer",
                          "description": "Rows that received a value."
                        },
                        "failedRows": {
                          "type": "integer",
                          "description": "Rows the engine could not compute."
                        },
                        "creditsUsed": {
                          "type": "integer",
                          "description": "Credits consumed by this run so far."
                        },
                        "creditsPerRow": {
                          "type": "integer",
                          "description": "Credits charged per computed row at the rate that applied when the run started."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "When the run was created."
                        },
                        "startedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time",
                          "description": "When processing began; null while pending."
                        },
                        "completedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time",
                          "description": "When the run finished; null until then and for a cancelled run."
                        },
                        "cancelledAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time",
                          "description": "When the run was cancelled by a newer run or a prompt edit; null otherwise."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "job": {
                    "id": "68a1f6109c41d20014b3ec21",
                    "status": "processing",
                    "mode": "initial",
                    "runOn": "first_100",
                    "totalRows": 100,
                    "processedRows": 40,
                    "successfulRows": 38,
                    "failedRows": 2,
                    "creditsUsed": 800,
                    "creditsPerRow": 20,
                    "createdAt": "2026-08-20T09:15:00.000Z",
                    "startedAt": "2026-08-20T09:15:02.000Z",
                    "completedAt": null,
                    "cancelledAt": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Progress of one smart-column run: the `jobId` returned by create, rerun, or a prompt edit. `status` moves from `pending` to `processing` and ends as `completed`, `partially_completed` (some rows failed), `failed` or `cancelled` (superseded by a newer run or a prompt edit). `processedRows`, `successfulRows` and `failedRows` count against `totalRows`, and `creditsUsed` is what the run has consumed so far at `creditsPerRow`. `mode` says why the run exists: `initial` for the column's first run, `all` or `new_only` for a rerun, `refresh` for the re-run a prompt edit starts, `single_row` for an automation. Poll every few seconds until the status is terminal; the values are then on `GET /business/lists/{listId}/rows` under `columnValues[columnId]`. Free to call.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id belongs to you.\n- `404` `JOB_NOT_FOUND` — No run with that jobId exists on this list.\n- `422` `VALIDATION_FAILED` — The path, query or body failed validation; `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the lists bucket, which every /business/lists endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/lists/{listId}/smart-columns/{columnId}": {
      "get": {
        "operationId": "getSmartColumn",
        "summary": "A smart column's definition and run state",
        "tags": [
          "Smart columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "Id of the list that owns the smart column.",
            "schema": {
              "type": "string",
              "description": "Id of the list that owns the smart column."
            }
          },
          {
            "name": "columnId",
            "in": "path",
            "required": true,
            "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns.",
            "schema": {
              "type": "string",
              "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "column"
                  ],
                  "properties": {
                    "column": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "prompt",
                        "engine",
                        "providerIds",
                        "refreshableRowCount",
                        "creditsPerRow",
                        "hasActiveJob"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Id of the column on the list."
                        },
                        "name": {
                          "type": "string",
                          "description": "Display name of the column."
                        },
                        "prompt": {
                          "type": "string",
                          "description": "The research instruction each row is computed from."
                        },
                        "engine": {
                          "type": "string",
                          "enum": [
                            "standard",
                            "deep_research"
                          ],
                          "description": "Engine that researches each row."
                        },
                        "providerIds": {
                          "type": [
                            "array",
                            "null"
                          ],
                          "items": {
                            "type": "string"
                          },
                          "description": "Deep Research provider slugs this column is restricted to; null when it may use every provider available to your workspace."
                        },
                        "refreshableRowCount": {
                          "type": "integer",
                          "description": "Rows a prompt edit or a `mode: all` rerun would recompute (upper bound)."
                        },
                        "creditsPerRow": {
                          "type": "integer",
                          "description": "Credits charged per computed row: the rate of the latest run, or the engine's current rate if the column has not run yet."
                        },
                        "hasActiveJob": {
                          "type": "boolean",
                          "description": "True while a run is pending or processing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "column": {
                    "id": "68a1f3009c41d20014b3e9a1",
                    "name": "Hiring signals",
                    "prompt": "Is this company hiring for sales roles right now? Answer yes or no and name the role.",
                    "engine": "deep_research",
                    "providerIds": [
                      "exa",
                      "firecrawl"
                    ],
                    "refreshableRowCount": 100,
                    "creditsPerRow": 100,
                    "hasActiveJob": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The column's stored definition and run state: its prompt, engine and any Deep Research provider restriction (`providerIds`, null when the column may use every provider), plus what a re-run would cost — `refreshableRowCount` rows (computed cells plus cells a cancelled run left pending or running) at `creditsPerRow` credits each — and `hasActiveJob`, true while a run is pending or processing (starting another run or editing the prompt cancels it). Only smart columns answer here; a plain custom column id is a 404. Free to call.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id belongs to you.\n- `404` `COLUMN_NOT_FOUND` — No smart column with that id is on this list (a plain custom column answers this too).\n- `422` `VALIDATION_FAILED` — The path, query or body failed validation; `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the lists bucket, which every /business/lists endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: lists."
      },
      "patch": {
        "operationId": "updateSmartColumn",
        "summary": "Rename a smart column, change its prompt or providers",
        "tags": [
          "Smart columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "Id of the list that owns the smart column.",
            "schema": {
              "type": "string",
              "description": "Id of the list that owns the smart column."
            }
          },
          {
            "name": "columnId",
            "in": "path",
            "required": true,
            "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns.",
            "schema": {
              "type": "string",
              "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "column",
                    "jobId"
                  ],
                  "properties": {
                    "column": {
                      "type": "object",
                      "required": [
                        "id",
                        "name"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Id of the column."
                        },
                        "name": {
                          "type": "string",
                          "description": "The column's stored name after the update."
                        }
                      }
                    },
                    "jobId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Id of the billed re-run a prompt change started; null when nothing was recomputed (a rename, a provider change, or a prompt edit with no computed row left to refresh)."
                    }
                  }
                },
                "example": {
                  "column": {
                    "id": "68a1f3009c41d20014b3e9a1",
                    "name": "Hiring signals v2"
                  },
                  "jobId": null
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Renames the column, changes its prompt, or changes a Deep Research column's provider restriction (`providerIds: null` clears it). A rename or a provider change is immediate and free, and new providers apply from the next run. A prompt change is not free — any run in progress is cancelled and every row the column has already computed (plus cells the cancelled run left pending or running) is immediately recomputed with the new prompt, each billed at the column's per-row rate; the new prompt is saved either way. The call answers 200 in every case: `jobId` carries the id of the re-run a prompt change started — poll it on `GET /business/lists/{listId}/smart-columns/{jobId}/status` — and is null when nothing was recomputed, which covers a rename, a provider change, and a prompt edit on a column with no computed row left to refresh. Check `refreshableRowCount × creditsPerRow` on `GET …/smart-columns/{columnId}` before a prompt edit, and expect 402 when your balance cannot cover the re-run. The response always carries the column's stored name, so a prompt-only edit still reports it.\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — Your credit balance cannot cover the re-run a prompt edit starts (refreshableRowCount × creditsPerRow); nothing was started or charged.\n- `404` `LIST_NOT_FOUND` — No list with that id belongs to you.\n- `404` `COLUMN_NOT_FOUND` — No smart column with that id is on this list, or the column has never run (nothing to recompute from).\n- `409` `COLUMN_NAME_TAKEN` — Another column on this list already has that name.\n- `422` `COLUMN_NAME_RESERVED` — The new name is one of the reserved built-in column names.\n- `422` `PROVIDERS_NOT_SUPPORTED` — providerIds was sent for a standard-engine column; only a deep_research column can be restricted to specific providers.\n- `422` `INVALID_REQUEST` — CRM rejected the change for a reason with no more specific code.\n- `422` `VALIDATION_FAILED` — The body failed validation, including a body with none of name, prompt or providerIds.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the lists bucket, which every /business/lists endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "New display name (1-100 characters, trimmed). Must stay unique on the list and must not be a reserved built-in column name."
                  },
                  "prompt": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "New research instruction (1-2000 characters, trimmed). Changing the prompt immediately recomputes the rows the column has already computed (plus cells a cancelled run left pending or running), cancelling any run in progress and billing each recomputed row at the column's per-row credit rate."
                  },
                  "providerIds": {
                    "type": [
                      "array",
                      "null"
                    ],
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 64,
                      "description": "A Deep Research provider id: the `id` (catalog slug, for example `zerobounce`) of an entry returned by GET /business/research/providers, not a Mongo id."
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "deep_research columns only: replace the provider restriction with these provider ids — the `id` values returned by GET /business/research/providers — or null to clear it and let the column use every provider available to your workspace. The ids are an allowlist, not an order: the run may call any of them, chooses per row, and need not use them all; the order you send them in is ignored. Send 1 to 50 distinct ids — an empty array or a repeated id is rejected. Ids are never checked against the catalog: a typo, a provider whose `allowedInRuns` is false, or a `byok-required` provider you have not saved a key for is accepted and then silently dropped from the run, and if none of the ids survive that check the rows are researched only by the providers Fuse always includes, so the answers come back far thinner than you asked for with no error anywhere. The new selection is free, recomputes nothing on its own and applies from the next run; sent for a standard-engine column it is rejected with 422 PROVIDERS_NOT_SUPPORTED."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/smart-columns/{columnId}/rerun": {
      "post": {
        "operationId": "rerunSmartColumn",
        "summary": "Run a smart column again",
        "tags": [
          "Smart columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "Id of the list that owns the smart column.",
            "schema": {
              "type": "string",
              "description": "Id of the list that owns the smart column."
            }
          },
          {
            "name": "columnId",
            "in": "path",
            "required": true,
            "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns.",
            "schema": {
              "type": "string",
              "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jobId",
                    "columnId",
                    "mode"
                  ],
                  "properties": {
                    "jobId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Id of the run that was started."
                    },
                    "columnId": {
                      "type": "string",
                      "description": "Id of the column being recomputed."
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "all",
                        "new_only"
                      ],
                      "description": "The mode the run was started with."
                    }
                  }
                },
                "example": {
                  "jobId": "68a1f6109c41d20014b3ec22",
                  "columnId": "68a1f3009c41d20014b3e9a1",
                  "mode": "new_only"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Runs the column again. `mode: all` recomputes every row the column covers (its stored `filters` still apply); `mode: new_only` computes only rows that have never been computed, which is how you fill the rows the first run's `runOn` left out or rows added to the list since. Either mode cancels a run still in progress and bills every row it will compute at the column's per-row rate up front: 402 when your balance cannot cover it, 422 NO_ROWS_TO_RESEARCH when there is nothing to compute. Asynchronous: answers 202 with the new `jobId`; poll `GET /business/lists/{listId}/smart-columns/{jobId}/status`.\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — Your credit balance cannot cover the rows this run would compute (rows × creditsPerRow); nothing was started or charged.\n- `404` `LIST_NOT_FOUND` — No list with that id belongs to you.\n- `404` `COLUMN_NOT_FOUND` — No smart column with that id is on this list, or the column has never run.\n- `422` `NO_ROWS_TO_RESEARCH` — Nothing to compute: no covered row is uncomputed (new_only) or the list has no covered rows.\n- `422` `INVALID_REQUEST` — CRM rejected the rerun for a reason with no more specific code.\n- `422` `VALIDATION_FAILED` — The path, query or body failed validation; `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the lists bucket, which every /business/lists endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "all",
                      "new_only"
                    ],
                    "default": "all",
                    "description": "Which rows to compute: all recomputes every covered row; new_only computes only rows that have never been computed. Either mode cancels a run still in progress, and each computed row is billed at the column's per-row credit rate. Defaults to all."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/rows/{contactId}/columns/{columnId}/provenance": {
      "get": {
        "operationId": "getSmartColumnCellProvenance",
        "summary": "Where a smart-column cell's value came from",
        "tags": [
          "Smart columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "Id of the list that owns the smart column.",
            "schema": {
              "type": "string",
              "description": "Id of the list that owns the smart column."
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "description": "Id of the row whose cell to inspect: the row id from GET /business/lists/{listId}/rows (a contact id on contact lists, a company id on company lists).",
            "schema": {
              "type": "string",
              "description": "Id of the row whose cell to inspect: the row id from GET /business/lists/{listId}/rows (a contact id on contact lists, a company id on company lists)."
            }
          },
          {
            "name": "columnId",
            "in": "path",
            "required": true,
            "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns.",
            "schema": {
              "type": "string",
              "description": "Id of the smart column, as returned when it was created or listed by GET /business/lists/{listId}/columns."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "provenance"
                  ],
                  "properties": {
                    "provenance": {
                      "type": "object",
                      "required": [
                        "reasoning",
                        "researchSteps",
                        "sourceUrls",
                        "errorMessage",
                        "fetchedAt"
                      ],
                      "properties": {
                        "reasoning": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The engine's explanation of the value; null when the run recorded none."
                        },
                        "researchSteps": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The steps the engine took, in order; empty when none were recorded."
                        },
                        "sourceUrls": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Pages and references the engine read; empty when none were recorded."
                        },
                        "errorMessage": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Why the row failed, when it did."
                        },
                        "fetchedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time",
                          "description": "When the cell was last computed."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "provenance": {
                    "reasoning": "The contact has 22 years of HR experience and currently holds a Recruitment Specialist role, with prior mid-senior titles such as Sr. Human Resources Generalist, which places them mid-level overall.",
                    "researchSteps": [
                      "Found the LinkedIn profile for LaShawnda Spencer with a detailed career history.",
                      "Current job title is Recruitment Specialist with seniority listed as Entry level.",
                      "Previous roles include mid-senior positions such as Sr. Human Resources Generalist and Recruitment Manager.",
                      "Overall seniority assessed as mid-level based on career progression and roles held."
                    ],
                    "sourceUrls": [
                      "https://linkedin.com/in/lashawnda-spencer-55555b17"
                    ],
                    "errorMessage": null,
                    "fetchedAt": "2026-08-25T11:16:53.898Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "How one smart-column cell got its value: the engine's `reasoning`, the `researchSteps` it took, the `sourceUrls` it read, an `errorMessage` when the row failed, and `fetchedAt`, when the cell was last computed. Provenance is written per cell by each run, so a cell no run has computed yet answers 404 PROVENANCE_NOT_FOUND and a column id that is not a smart column on this list answers 404 COLUMN_NOT_FOUND. The row is addressed by its list row id — a contact id on contact lists, a company id on company lists. Free to call.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id belongs to you.\n- `404` `COLUMN_NOT_FOUND` — No smart column with that id is on this list (a plain custom column answers this too).\n- `404` `PROVENANCE_NOT_FOUND` — The column exists but no run has computed that row, so there is no provenance to show.\n- `422` `VALIDATION_FAILED` — The path, query or body failed validation; `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the lists bucket, which every /business/lists endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/lists/{listId}/columns/{columnId}/values": {
      "patch": {
        "operationId": "updateColumnValues",
        "summary": "Write custom column values (keyed by contact id)",
        "tags": [
          "Custom columns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          },
          {
            "name": "columnId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the custom column (from GET /business/lists/{listId}/columns).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the custom column (from GET /business/lists/{listId}/columns)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "updatedCount"
                  ],
                  "properties": {
                    "updatedCount": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "updatedCount": 2
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Writes cell values into one custom column, keyed by contact (row) id — the write path for externally generated data. A cell takes a string (also accepted for `number`, `boolean` and `date` columns and parsed against the column's type), a number, a boolean, or — for a `url` column only — `{ label, value }`. Up to 500 cells per call; a value the list service refuses for the column's type answers 422 INVALID_REQUEST. `updatedCount` echoes how many entries were submitted, not how many cells changed.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — The list — or the column on it — was not found for the token owner.\n- `422` `INVALID_REQUEST` — The list service rejected one or more values for the column's type.\n- `422` `VALIDATION_FAILED` — values missing/empty/over 500, a non-24-hex contactId, or a value in none of the accepted shapes.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "values": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "contactId": {
                          "type": "string",
                          "description": "24-character hex id of a contact (the row id from GET /business/lists/{listId}/rows)."
                        },
                        "value": {
                          "anyOf": [
                            {
                              "type": "string",
                              "maxLength": 5000,
                              "description": "Text value (max 5000 characters). An empty or whitespace-only string CLEARS the cell for every column type. On a number column the text must parse as a finite number, on a boolean column it must be exactly true or false (any casing), and on a date column anything Date.parse accepts — ISO-8601 is the safe form; anything else answers 422."
                            },
                            {
                              "type": "number",
                              "description": "Numeric value for a number column (also accepted by a string column, which stores its text form)."
                            },
                            {
                              "type": "boolean",
                              "description": "true/false for a boolean column (also accepted by a string column, which stores true or false as text)."
                            },
                            {
                              "type": "object",
                              "properties": {
                                "label": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 5000,
                                  "description": "Display text for the link (1-5000 characters)."
                                },
                                "value": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 5000,
                                  "description": "The link URL (1-5000 characters). Must be absolute and http:// or https:// — a bare domain such as acme.com, or any other scheme, answers 422."
                                }
                              },
                              "required": [
                                "label",
                                "value"
                              ],
                              "description": "Link object for a url column: label (display text) plus value (the URL)."
                            }
                          ],
                          "description": "The cell value. Accepted values: a string (also accepted for number, boolean and date columns and parsed against the column type — an empty string clears the cell), a number, a boolean, or — for a url column only, which accepts nothing else — an object with non-empty label and an absolute http(s) value."
                        }
                      },
                      "required": [
                        "contactId",
                        "value"
                      ],
                      "description": "One cell write: the contact (row) and the value to store in the column for it."
                    },
                    "minItems": 1,
                    "maxItems": 500,
                    "description": "Cells to write, at most 500 per call: each entry is an independent write of one contact's cell in this column, and entries do not combine — send at most one entry per contact, because two entries for the same contact are applied concurrently and which value survives is undefined. Every contactId must already be a row of this list, and every value must convert to the column's type, or the call answers 422 — a type failure is caught before anything is written, but an entry rejected for not being on the list can leave siblings from the same call already written. The response's updatedCount is the number of entries submitted, not the number of cells changed. See `value` for the accepted values per column type."
                  }
                },
                "required": [
                  "values"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/enrich": {
      "post": {
        "operationId": "enrichList",
        "summary": "Enrich a list's contacts in place",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "listIds",
                    "mode",
                    "totalContacts",
                    "estimatedMinutes"
                  ],
                  "properties": {
                    "listIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "email",
                        "phone",
                        "phone_and_email",
                        "validate_emails",
                        "demographics"
                      ]
                    },
                    "totalContacts": {
                      "type": "integer"
                    },
                    "estimatedMinutes": {
                      "type": "integer"
                    },
                    "jobId": {
                      "type": "string",
                      "description": "Waterfall modes only: the run's job, to poll at GET /business/jobs/{jobId}."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "processing"
                      ],
                      "description": "Waterfall modes only: pending while the job waits behind your other enrichment job, processing once it runs."
                    }
                  }
                },
                "example": {
                  "listIds": [
                    "68a1f20b9c41d20014b3e901"
                  ],
                  "mode": "phone_and_email",
                  "totalContacts": 200,
                  "estimatedMinutes": 10,
                  "jobId": "68a2109c9c41d20014b41002",
                  "status": "pending"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Runs an enrichment over the list's contacts in place. `mode` selects what runs: the waterfall modes (`email`, `phone`, `phone_and_email`) discover new values through the provider waterfall and take an optional row `filters` object or an explicit `contactIds` selection; `validate_emails` re-verifies the contacts' existing emails; `demographics` resolves manually-added rows to canonical contacts. `limit` is how many rows are taken, from `offset` (default 0) in the list's default order after `filters` — required unless `contactIds` is given, and capped at 5,000 for `validate_emails`/`demographics`. Rows that already hold the requested data, or were searched for it before, are skipped and not charged but still count toward `limit`, so a repeated call with the same `offset` and `limit` takes the same rows: pass a larger `offset` to reach rows further down. A call identical to one whose job is still queued or running (same `mode`, `filters`, `offset` and `limit`) returns that job instead of starting another. Billing is per processed contact: up to 50 credits per work email (100 when personal emails are prioritised in the workspace settings), 200 per phone, 10 per re-verified address, 2 per resolved demographics row; the balance must cover the reserved price up front (402 INSUFFICIENT_CREDITS) and contacts already carrying the requested data are never re-charged — with the waterfall modes a fully enriched list answers 409 ALL_CONTACTS_ALREADY_ENRICHED before anything bills, while `validate_emails` and `demographics` report a nothing-to-do run as 202 with `totalContacts: 0`. Async: `totalContacts` is the number of rows this run takes (at most `limit`, fewer at the list's end; a call that returns a running job, or explicit `contactIds` that join a queued one, answers that job's total) and `estimatedMinutes` a rough duration; poll `GET /business/lists/{listId}/rows` (emails/phones fill in) or the list's `metrics`. The waterfall modes run as a job: the 202 also carries its `jobId` and `status` (`pending` while it waits behind your other enrichment job, `processing` once it runs); poll `GET /business/jobs/{jobId}` for its status and counts. A job whose balance runs out mid-run pauses (`stopped`, with `pausedReason` INSUFFICIENT_CREDITS) and is resumed from the app. To work through a list in batches, pass `offset` as the previous call's `offset` plus `limit`: a call without `offset` always starts at the list's first row.\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — The credit balance does not cover the reserved price for the requested rows.\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `409` `ALL_CONTACTS_ALREADY_ENRICHED` — Every contact in the list already carries the requested data; nothing to run. Waterfall modes (email, phone, phone_and_email) only — validate_emails and demographics answer 202 with totalContacts 0 instead.\n- `422` `CONTACT_LIST_REQUIRED` — The list is a company list; enrichment runs on contacts.\n- `422` `CONTACT_NOT_IN_LIST` — A contactIds entry is not a row of this list.\n- `422` `VALIDATION_FAILED` — mode missing/unknown, limit missing without contactIds or outside 1-10000, filters/contactIds sent together or with validate_emails/demographics, offset sent with contactIds or with validate_emails/demographics.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "mode": {
                    "type": "string",
                    "enum": [
                      "email",
                      "phone",
                      "phone_and_email",
                      "validate_emails",
                      "demographics"
                    ],
                    "description": "What to run: email, phone or phone_and_email discover new values through the enrichment waterfall (billed per contact processed, at up to 50 credits per work email — 100 when personal emails are prioritised — and 200 per phone); validate_emails re-verifies the contacts' existing emails (10 credits per address); demographics resolves manually uploaded rows to canonical contacts (2 credits per resolved contact)."
                  },
                  "offset": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "Rows to skip before taking limit of them (waterfall modes only, default 0). A repeated call with the same offset and limit takes the same rows; pass a larger offset to reach rows further down the list. Not allowed with contactIds."
                  },
                  "filters": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact full name (contact lists). Free text: each value is matched as a case-insensitive substring of firstName + space + lastName, so Ana matches Ana Silva."
                      },
                      "title": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Job title (contact lists). Free text: each value is matched as a case-insensitive substring of the stored job title, so vp also matches VP of Sales. There is no fixed vocabulary — `GET /business/prospects/autocomplete?field=title&q=` suggests the titles the enrichment provider knows."
                      },
                      "dept": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Department (contact lists). Matched as a case-insensitive substring of the contact's department, whose values come from the provider's job_title_role vocabulary — take them from `GET /business/prospects/filter-options` (field `job_title_role`: sales, engineering, human_resources, …). A contact with several roles stores them comma-joined, which a substring match still finds. Any other text is accepted and matches only rows that literally contain it."
                      },
                      "level": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Seniority level (contact lists). Matched EXACTLY (case-insensitive, whole value) against the contact's level, whose values come from the provider's job_title_levels vocabulary — take them from `GET /business/prospects/filter-options` (field `job_title_levels`): cxo, director, entry, manager, owner, partner, senior, training, unpaid, vp. A contact carrying several levels stores them comma-joined (cxo, owner) and an exact match on one level does NOT find it; any other value is accepted and matches nothing."
                      },
                      "industryName": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's industry (contact lists). Matched EXACTLY (case-insensitive, whole value) against the industry on the contact, which the enrichment provider fills from its own 147-value list — take the values from `GET /business/prospects/filter-options` (field `industry`, e.g. computer software, hospital & health care). A near-miss such as Software is accepted and matches nothing."
                      },
                      "country": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's country (contact lists). Matched EXACTLY (case-insensitive, whole value) against the country of the contact's address, stored as the provider spells it (united states, not US) — take the values from `GET /business/prospects/filter-options` (field `location_country`). An ISO code or another spelling is accepted and matches nothing."
                      },
                      "state": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's state or region (contact lists). Matched EXACTLY (case-insensitive, whole value) against the state of the contact's address — the provider's region name, e.g. california. There is no enum; `GET /business/prospects/autocomplete?field=region&q=` suggests from the same region vocabulary. A spelling no row carries is accepted and matches nothing."
                      },
                      "personalLocation": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Contact's location text (contact lists). Each value is matched as a case-insensitive substring against the contact's city, state AND country separately, and the row matches when any one of the three contains it — so pass ONE component (buenos aires, or california, or united states), never a whole line like san francisco, california, united states, which matches no component. No endpoint serves the city names: read the stored components off the rows themselves, where `GET /business/lists/{listId}/rows` returns each row's `location` as {city, state, country}. For the other two components, `GET /business/prospects/autocomplete?field=region&q=` suggests the state/region names and `GET /business/prospects/filter-options` (field `location_country`) lists the country names. Do NOT feed this key from `GET /business/prospects/autocomplete?field=location`: that endpoint returns whole city, state, country lines, which are exactly the shape that matches no component."
                      },
                      "companyName": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company name (both list kinds). Free text: each value is matched as a case-insensitive substring of the company name. On a company list, `GET /business/lists/{listId}/filter-values?field=name` returns the exact names that list holds."
                      },
                      "companyIndustry": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company industry (both list kinds). Matched as a case-insensitive substring of the company's industry, filled by the enrichment provider from its own list — take the values from `GET /business/prospects/filter-options` (field `job_company_industry`). Do not use the company-search vocabulary from /business/companies/filter-options: that is a different provider's list and its values are not what these rows store."
                      },
                      "companyHeadQuartersCountry": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company headquarters country (both list kinds). Matched EXACTLY (case-insensitive, whole value), but each value is first expanded to every spelling of that country (full name, ISO-3166 alpha-2 and alpha-3), because the field mixes both vocabularies — so the full country name alone is enough. Take the names from `GET /business/prospects/filter-options` (field `location_country`); a value that resolves to no country is matched verbatim."
                      },
                      "companyLocation": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company location text (contact lists). Each value is matched as a case-insensitive substring against the company address's city, state AND country separately, and the row matches when any one of the three contains it, so pass ONE component. Many companies are stored with a country and nothing else, in which case a city or state value is accepted and matches nothing; `GET /business/prospects/filter-options` (field `location_country`) lists the country names."
                      },
                      "website": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Company web domain (both list kinds). Matched EXACTLY (case-insensitive, whole value) against the stored domain, so pass the BARE domain — brightpay.com. A full URL (https://brightpay.com/), a www. prefix or a partial domain is accepted and matches nothing. On a company list, `GET /business/lists/{listId}/filter-values?field=domain` returns the exact domains that list holds."
                      },
                      "numberOfEmployees": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                {
                                  "type": "number"
                                }
                              ]
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted range labels, OR-joined: a row matches when any one of them matches (at most 200)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to keep, OR-joined: a row matches when any one of them matches (at most 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to drop: a row is dropped when it matches any one of them (at most 200)."
                              }
                            }
                          }
                        ],
                        "description": "Company size (both list kinds). Each value is parsed as a headcount range and matched against the company's LinkedIn head count; accepted values are a range (\"51-200\"), an open top end (\"10001+\") or a bare head count (\"500\", meaning exactly 500). Send every value as a JSON STRING: an unquoted JSON number passes validation and then throws while the range is parsed, so the call answers 500 UNEXPECTED_ERROR instead of filtering. The provider's own labels — 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+, served by `GET /business/prospects/filter-options` (field `job_company_size`) — all parse. Anything else is read with parseInt, so a value that STARTS with digits silently narrows to that one number (\"51 to 200\" matches companies with exactly 51 employees, it is not ignored) and a value that does not (\"Enterprise\") is silently dropped; if every value is dropped nothing is left to match and the call answers zero rows rather than ignoring the filter, and companies with no stored head count never match."
                      },
                      "revenue": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                {
                                  "type": "number"
                                }
                              ]
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted range labels, OR-joined: a row matches when any one of them matches (at most 200)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to keep, OR-joined: a row matches when any one of them matches (at most 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "minLength": 1,
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "number"
                                    }
                                  ]
                                },
                                "maxItems": 200,
                                "description": "Range labels to drop: a row is dropped when it matches any one of them (at most 200)."
                              }
                            }
                          }
                        ],
                        "description": "Company revenue (contact lists). Accepted values: a plain number, matched for exact equality against the company's stored revenue. The enrichment provider stores revenue as a LABEL (for example $10m-$25m), and a label is coerced to a number before matching, so a label — or any other non-numeric value — is accepted and matches nothing. Use numberOfEmployees to narrow by company size instead."
                      },
                      "keywords": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500,
                        "description": "Wildcard search over the contact's job title only (contact lists) — it matches no other field. Free text: every character is matched literally except the two wildcards, `*` for any run of characters and `?` for any single one, the match is case-insensitive and unanchored (vp matches VP of Sales), and the regex characters . ^ $ + ( ) [ ] { } | \\ are rejected with 422."
                      },
                      "linkedinUrl": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 500,
                        "description": "LinkedIn URL (contact lists). One value, matched as a case-insensitive substring of the stored URL, which is kept scheme-less and www-less as linkedin.com/in/<slug> — so pass the slug or linkedin.com/in/<slug>. A full https://www.linkedin.com/in/<slug> is longer than the stored value, so it is accepted and matches nothing."
                      },
                      "enrichedEmail": {
                        "type": "object",
                        "properties": {
                          "include": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched",
                                "no_emails_found"
                              ]
                            },
                            "description": "Statuses to keep: enriched, not_enriched, no_emails_found. A contact is kept when it is in any one of the listed states (OR-joined), so listing every state keeps every row."
                          },
                          "exclude": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched",
                                "no_emails_found"
                              ]
                            },
                            "description": "Statuses to drop: enriched, not_enriched, no_emails_found. The states are OR-joined: a contact in any one of them is dropped."
                          }
                        },
                        "description": "Email enrichment state (contact lists). One of exactly: enriched (an email was found), not_enriched (never attempted) or no_emails_found (attempted, nothing found)."
                      },
                      "enrichedPhone": {
                        "type": "object",
                        "properties": {
                          "include": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched"
                              ]
                            },
                            "description": "Statuses to keep: enriched, not_enriched. A contact is kept when it is in any one of the listed states (OR-joined), so listing both states keeps every row."
                          },
                          "exclude": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "enriched",
                                "not_enriched"
                              ]
                            },
                            "description": "Statuses to drop: enriched, not_enriched. The states are OR-joined: a contact in any one of them is dropped."
                          }
                        },
                        "description": "Phone enrichment state (contact lists). One of exactly: enriched (a phone was found) or not_enriched (no phone yet)."
                      },
                      "emailValidity": {
                        "type": "object",
                        "properties": {
                          "include": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "valid",
                                "invalid",
                                "catch-all",
                                "unknown",
                                "do_not_mail",
                                "personal",
                                "unverified"
                              ]
                            },
                            "description": "Statuses to keep: valid, invalid, catch-all, unknown, do_not_mail, personal, unverified. OR-joined over statuses and over the contact's addresses: a contact is kept when any one of its emails carries any one of the listed statuses."
                          },
                          "exclude": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "valid",
                                "invalid",
                                "catch-all",
                                "unknown",
                                "do_not_mail",
                                "personal",
                                "unverified"
                              ]
                            },
                            "description": "Statuses to drop: valid, invalid, catch-all, unknown, do_not_mail, personal, unverified. OR-joined over statuses and over the contact's addresses: a contact is dropped when any one of its emails carries any one of the listed statuses."
                          }
                        },
                        "description": "Validation status of the contact's emails (contact lists). One of exactly: valid, invalid, catch-all, unknown, do_not_mail, personal, unverified — valid means a deliverable WORK address (personal ones are excluded from it), personal means a deliverable personal address, and unverified means a user-uploaded address that was never verified."
                      },
                      "icpMatch": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "yes",
                                "no"
                              ]
                            },
                            "minItems": 1,
                            "description": "Accepted values: exactly one of [\"yes\"] (ICP-matched rows) or [\"no\"] (the rest); [\"yes\",\"no\"] is read as [\"yes\"]."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "yes",
                                    "no"
                                  ]
                                }
                              }
                            }
                          }
                        ],
                        "description": "ICP match outcome (contact lists). Accepted values: exactly one of yes (rows matching the ICP saved in the app) or no (the rest). When the workspace has no ICP configured nothing is a match, so yes returns no rows at all and no returns every row."
                      },
                      "campaignEngagement": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "Campaign engagement bucket (both list kinds). One of exactly: contacted (at least one campaign email has been sent to the contact), in_active_campaign (targeted by a running campaign, nothing sent yet) or never_engaged (neither) — compared as whole values, case included, so any other value is accepted and returns no rows. A company's bucket is the highest bucket among its contacts."
                      },
                      "otherLists": {
                        "anyOf": [
                          {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "maxItems": 200,
                            "minItems": 1,
                            "description": "Accepted values, OR-joined: a row matches when any one of them matches (1-200 values, max 500 characters each)."
                          },
                          {
                            "type": "object",
                            "properties": {
                              "include": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to keep, OR-joined: a row matches when any one of them matches (up to 200)."
                              },
                              "exclude": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 500
                                },
                                "maxItems": 200,
                                "description": "Values to drop: a row is dropped when it matches any one of them (up to 200)."
                              }
                            },
                            "description": "Explicit include/exclude lists; include is OR-joined, exclude drops a row matching any of its values."
                          }
                        ],
                        "description": "NAMES (not ids) of other lists the contact must — or with exclude, must not — also belong to (contact lists). Each value is matched as a case-insensitive substring of the list names from `GET /business/lists`; only the team's static contact lists are searched, so the list being read, dynamic lists and archived lists never satisfy it."
                      },
                      "customColumns": {
                        "type": "object",
                        "properties": {},
                        "description": "Cell filters keyed by custom/smart column id (from `GET /business/lists/{listId}/columns`), both list kinds. Every column listed must match (AND-ed); a column id that is not on this list matches no row."
                      }
                    },
                    "description": "Row-filter object narrowing which contacts the waterfall modes process, in the same language as the filters query of GET /business/lists/{listId}/rows; not allowed for validate_emails or demographics and mutually exclusive with contactIds. Text keys (name, title, dept, level, industryName, country, state, personalLocation, companyName, companyIndustry, companyHeadQuartersCountry, companyLocation, website, campaignEngagement, otherLists) take an array of accepted values, e.g. {\"companyName\":[\"pomelo\"]} or {\"country\":[\"argentina\"]}, or {\"include\":[...],\"exclude\":[...]} — otherLists takes list NAMES, not ids; numberOfEmployees takes headcount ranges the same way but as STRINGS (\"51-200\", \"10001+\" or a bare head count \"500\" — an unquoted JSON number answers 500) and revenue a plain number; keywords (a wildcard match on the job title only) and linkedinUrl take one string; enrichedEmail, enrichedPhone and emailValidity take {\"include\":[...]} of their statuses; icpMatch takes [\"yes\"] or [\"no\"]; customColumns maps a column id to {\"dataType\":\"string\",\"include\":[...]}, {\"dataType\":\"boolean\",\"value\":true} or {\"dataType\":\"number\",\"rangeMin\":1,\"rangeMax\":10}. Company lists honour companyName, companyIndustry, companyHeadQuartersCountry, website, numberOfEmployees, campaignEngagement and customColumns. Every key is optional; an unknown key or a wrong value shape is rejected rather than ignored. Values inside one key are OR-joined and different keys are AND-ed. VALUES ARE NOT VALIDATED: level, industryName, country, state, website and companyHeadQuartersCountry are matched as whole values and campaignEngagement, icpMatch and enum cells as exact strings, so a value in the wrong vocabulary is accepted and silently matches nothing — each key's own description names its vocabulary and the endpoint that serves it. A rejected filter answers 422 VALIDATION_FAILED."
                  },
                  "contactIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "24-character hex id of a contact (the row id from GET /business/lists/{listId}/rows)."
                    },
                    "minItems": 1,
                    "maxItems": 500,
                    "description": "Explicit contacts to process (24-character hex ids, 1-500) for the waterfall modes. Each must be a row of this list (a row `id` from GET /business/lists/{listId}/rows); any other id answers 422 CONTACT_NOT_IN_LIST. Not allowed for validate_emails or demographics and mutually exclusive with filters."
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "How many rows to take, starting at offset, in the list's default order (oldest first) after filters (1-10000); required unless contactIds is given, and validate_emails/demographics cap it at 5000. Rows that already hold the requested data, or were searched for it before, are skipped and not charged but still count toward limit."
                  }
                },
                "required": [
                  "mode"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/crm-push": {
      "post": {
        "operationId": "pushListToCrm",
        "summary": "Push a list's contacts into a connected CRM",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "crm",
                    "listIds"
                  ],
                  "properties": {
                    "crm": {
                      "type": "string",
                      "enum": [
                        "hubspot",
                        "salesforce",
                        "zoho",
                        "attio",
                        "pipedrive"
                      ]
                    },
                    "listIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": {
                  "crm": "hubspot",
                  "listIds": [
                    "68a1f20b9c41d20014b3e901"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Pushes the list's contacts into a connected CRM. `crm` names which one (`hubspot`, `salesforce`, `zoho`, `attio`, `pipedrive`; several can be connected at once); the connection checked is the team's designated sync user's, so an unconnected CRM answers 422 CRM_NOT_CONNECTED. An explicit `contactIds` selection pushes just those contacts (the response still echoes the list id). Async, with no job to poll: the sync runs in the background against the field mapping saved in the app's CRM settings, and results appear in the CRM. No credits are spent.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `CONTACT_LIST_REQUIRED` — The list is a company list; the push sends contacts.\n- `422` `CRM_NOT_CONNECTED` — The team's sync user has no live connection to that CRM.\n- `422` `VALIDATION_FAILED` — crm missing or outside the supported set, or contactIds outside 1-500.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "crm": {
                    "type": "string",
                    "enum": [
                      "hubspot",
                      "salesforce",
                      "zoho",
                      "attio",
                      "pipedrive"
                    ],
                    "description": "Which connected CRM receives the contacts: hubspot, salesforce, zoho, attio or pipedrive; an unconnected CRM answers 422 CRM_NOT_CONNECTED."
                  },
                  "contactIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "24-character hex id of a contact (the row id from GET /business/lists/{listId}/rows)."
                    },
                    "minItems": 1,
                    "maxItems": 500,
                    "description": "Push only these contacts (24-character hex ids, at most 500) instead of every contact in the list: the ids are the selection, so every one of them is pushed and nothing else is. They are taken as given rather than intersected with the list, and sending them also makes the push overwrite fields on records that already exist in the CRM — pushing the whole list leaves those untouched."
                  }
                },
                "required": [
                  "crm"
                ]
              }
            }
          }
        }
      }
    },
    "/business/lists/{listId}/export": {
      "post": {
        "operationId": "exportList",
        "summary": "Start an async CSV export of a list (returns a jobId)",
        "tags": [
          "Exports"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "listId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the list (from GET /business/lists).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the list (from GET /business/lists)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jobId"
                  ],
                  "properties": {
                    "jobId": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "jobId": "68a1f5209c41d20014b3eb11"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Starts a CSV export of the whole list. Async: 202 returns a `jobId`; poll `GET /business/exports/{jobId}` (or `GET /business/jobs/{jobId}`) until `status` is `completed`, then download the file from the short-lived presigned `downloadUrl`. For a filtered export, copy the filtered rows into a list first (`POST /business/lists/save-to-list`). No credits are spent.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — No list with that id is visible to the token owner.\n- `422` `VALIDATION_FAILED` — listId is not a 24-hex id.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/exports/{jobId}": {
      "get": {
        "operationId": "getExport",
        "summary": "Poll an export job (presigned download URL when completed)",
        "tags": [
          "Exports"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of an async job, as returned with the 202 that started it (POST /business/lists/{listId}/export).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of an async job, as returned with the 202 that started it (POST /business/lists/{listId}/export)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "exportJob"
                  ],
                  "properties": {
                    "exportJob": {
                      "type": "object",
                      "required": [
                        "jobId",
                        "status",
                        "rowCount",
                        "downloadUrl",
                        "error"
                      ],
                      "properties": {
                        "jobId": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "processing",
                            "completed",
                            "failed"
                          ]
                        },
                        "rowCount": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "downloadUrl": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "error": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "LIST_NOT_FOUND",
                            "LIST_EMPTY",
                            "EXPORT_FAILED",
                            null
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "exportJob": {
                    "jobId": "68a1f5209c41d20014b3eb11",
                    "status": "completed",
                    "rowCount": 412,
                    "downloadUrl": "https://fuseai-csv-uploads.s3.us-east-1.amazonaws.com/exports/68a1f20b9c41d20014b3e901/68a1f5209c41d20014b3eb11.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Signature=3f6c2a9d1b8e4c7f",
                    "error": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Polls an export job started by `POST /business/lists/{listId}/export`. While it runs, `rowCount` and `downloadUrl` are null. When `status` is `completed`, `downloadUrl` is a short-lived presigned URL for the CSV (poll again for a fresh link once it expires) and `rowCount` is the number of rows written. When `status` is `failed`, `error` says why: `LIST_EMPTY` (nothing to export), `LIST_NOT_FOUND` (the list went away while the job ran) or `EXPORT_FAILED` (anything else — retry). Unknown or expired jobs answer 404 EXPORT_NOT_FOUND. `GET /business/jobs/{jobId}` reads the same record and maps `error` to the same three values.\n\nErrors:\n- `404` `EXPORT_NOT_FOUND` — No export job with that id (it may have expired or belong to another workspace).\n- `422` `VALIDATION_FAILED` — jobId is not a 24-hex id.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/campaigns": {
      "post": {
        "operationId": "createCampaign",
        "summary": "Create a draft campaign",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaignId": {
                      "type": "string",
                      "description": "Id of the new campaign; use it for every other campaign endpoint."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "initializing"
                      ],
                      "description": "A new campaign always starts as a draft in status initializing."
                    }
                  },
                  "required": [
                    "campaignId",
                    "status"
                  ]
                },
                "example": {
                  "campaignId": "6a8dce146dc0b3d9029c22d0",
                  "status": "initializing"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a draft campaign in status `initializing`; nothing is sent until you call POST /business/campaigns/{campaignId}/approve. `campaignType: manual` (the default) scaffolds one empty step per entry in `channels` immediately (sequenceNumber 0, 1, 2 ...), so you can list them with GET .../steps and write subject/body with PATCH .../steps/{stepId}. `campaignType: ai-generated` returns immediately and runs prompt analysis and topic generation in the background: poll GET /business/campaigns/{campaignId} until `initializationStatus` is `completed` (or `failed`, with the reason in `initializationError`) before editing or approving. Passing `templateId` copies that template's steps and channels for either type. The campaign is owned by the token owner. No credits are charged by this call. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `LIST_NOT_FOUND` — A listId/listIds entry does not exist, is archived, or belongs to another team.\n- `404` `TEMPLATE_NOT_FOUND` — templateId does not exist or is not visible to you.\n- `404` `WRITING_STYLE_NOT_FOUND` — writingStyleId (ai-generated only) is not one of your writing styles.\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — knowledgeHubId (ai-generated only) is not one of your non-archived knowledge hubs.\n- `422` `INVALID_CAMPAIGN_CHANNELS` — More than one linkedin_connection step, or a linkedin_connection after a linkedin_message (also evaluated on the template's steps when templateId is given).\n- `422` `LIST_INCOMPATIBLE_WITH_CHANNELS` — The source lists are empty, or no contact carries an email address (email/inmail) or a LinkedIn URL (LinkedIn channels) for the requested channels.\n- `422` `EXCLUDE_COMPANY_LISTS_INVALID` — An excludeCompanyLists entry is not a non-archived company or people list owned by your team.\n- `422` `VALIDATION_FAILED` — The body failed schema validation (unknown key, both or neither of listId/listIds, channels together with templateId, an AI-only field on a manual campaign, an unrecognised timezone, a non-http(s) ctaLink); `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "campaignName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Display name of the campaign (1-200 characters, trimmed); also the stem of the CSV export filename."
                  },
                  "listId": {
                    "type": "string",
                    "description": "Id of the single Fuse list the campaign sources contacts from; mutually exclusive with listIds (exactly one of the two is required). The list must belong to your team and not be archived, else 404 LIST_NOT_FOUND."
                  },
                  "listIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse list id (24-character hex ObjectId), as the `id` of a GET /business/lists row."
                    },
                    "minItems": 1,
                    "maxItems": 10,
                    "description": "Ids of 1-10 Fuse lists the campaign sources; mutually exclusive with listId. Every list must belong to your team and not be archived, else 404 LIST_NOT_FOUND. Take the ids from GET /business/lists with entityType=contactList — a campaign enrolls contacts. The lists are OR-joined into a deduplicated union: they are read in the order given and a contact that sits in two of them is enrolled once, up to the campaign's 10000-contact cap, after which the remaining lists are skipped."
                  },
                  "channels": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "email",
                        "linkedin_connection",
                        "linkedin_message",
                        "inmail"
                      ],
                      "description": "A step channel: email, linkedin_connection (connection request with optional note), linkedin_message (message to an accepted connection) or inmail (LinkedIn InMail, consumes the sender's InMail credits)."
                    },
                    "minItems": 1,
                    "maxItems": 10,
                    "description": "Ordered channel scaffold: one empty sequence step (sequenceNumber 0, 1, 2 ...) is created per entry, 1-10 entries, default [\"email\"]. At most one linkedin_connection, and it must precede every linkedin_message (422 INVALID_CAMPAIGN_CHANNELS). Forbidden together with templateId, whose steps decide the channels."
                  },
                  "campaignStartDate": {
                    "type": "string",
                    "description": "ISO 8601 date-time before which nothing is sent (default: now); evaluated in timezone together with emailDays."
                  },
                  "timezone": {
                    "type": "string",
                    "default": "UTC",
                    "description": "Time zone in which the daily sending window (09:00-17:00 local) and emailDays are evaluated; default UTC. Accepted values are IANA time zone names, for example America/New_York, Europe/Berlin, Asia/Kolkata or UTC. Do not send an abbreviation: EST is in the tz database but resolves to a fixed UTC-5 zone that never observes daylight saving, so name the region instead. A name the tz database does not know is rejected rather than silently evaluated as UTC."
                  },
                  "emailDays": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "Monday",
                        "Tuesday",
                        "Wednesday",
                        "Thursday",
                        "Friday",
                        "Saturday",
                        "Sunday"
                      ],
                      "description": "An English weekday name with a capital first letter (Monday ... Sunday)."
                    },
                    "minItems": 1,
                    "maxItems": 7,
                    "description": "Weekdays on which sends may go out; default Monday to Friday. One of exactly: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday — capitalised English names, nothing else. The days are OR-joined: a send that comes due is pushed forward to the next day named in the set, so a weekday you leave out is never used. 1-7 unique names; naming all seven removes the weekday restriction."
                  },
                  "excludeLists": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse list id (24-character hex ObjectId), as the `id` of a GET /business/lists row."
                    },
                    "maxItems": 10,
                    "description": "Ids of up to 10 Fuse people lists whose members are excluded from enrollment (a list that is also a source list is ignored here); default []. Take the ids from GET /business/lists with entityType=contactList. The lists are OR-joined: a contact is skipped when it appears in any one of them, matched on contact id, email address (case-insensitively) or LinkedIn URL. These ids are stored without an ownership check, so an id that is not one of your lists is accepted and silently excludes nobody — and a companyList here excludes nobody either, use excludeCompanyLists for that."
                  },
                  "excludeCompanyLists": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse list id (24-character hex ObjectId), as the `id` of a GET /business/lists row."
                    },
                    "maxItems": 20,
                    "description": "Ids of up to 20 company or people lists owned by your team whose companies' contacts are skipped at enrollment; default []. Take the ids from GET /business/lists — either entityType: a companyList contributes its companies, a contactList contributes the companies its contacts work at. The lists are OR-joined: a contact is skipped when its company appears in any one of them, matched by company id and by the company's web domain (personal-email domains are never used). Unlike excludeLists these ids are checked, so one that is unknown, archived or not your team's answers 422 EXCLUDE_COMPANY_LISTS_INVALID."
                  },
                  "excludeContacted": {
                    "type": "string",
                    "enum": [
                      "none",
                      "ever",
                      "last_1_month",
                      "last_3_months",
                      "last_6_months",
                      "last_1_year"
                    ],
                    "default": "none",
                    "description": "Skips contacts your campaigns already reached: none keeps them, ever excludes anyone ever messaged, last_1_month / last_3_months / last_6_months / last_1_year exclude those messaged within that window; contacts with a pending send in an active campaign are always excluded. Default none."
                  },
                  "excludeEngagedContacts": {
                    "type": "boolean",
                    "default": false,
                    "description": "When true, contacts who have already replied to one of your campaigns are excluded from enrollment. Default false."
                  },
                  "isDynamic": {
                    "type": "boolean",
                    "default": false,
                    "description": "When true, contacts added to the source lists after activation are enrolled automatically by a background refresh. Default false."
                  },
                  "useLinkedinPosts": {
                    "type": "boolean",
                    "default": false,
                    "description": "When true, each contact's recent LinkedIn posts are fetched at activation and fed to AI personalization (needs a LinkedIn URL on the contact). Default false."
                  },
                  "addUnsubscribeLink": {
                    "type": "boolean",
                    "default": true,
                    "description": "When true, every email step appends a one-click unsubscribe footer (email channel only). Default true."
                  },
                  "openRateTrackingEnabledAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ISO 8601 timestamp that switches on the open-tracking pixel for outgoing emails (it records when tracking was enabled); null (default) keeps open tracking off."
                  },
                  "sendOnlyToValidatedEmailsEnabledAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ISO 8601 timestamp from which enrollment only accepts contacts whose email verified as valid (catch-all and never-verified uploaded addresses are skipped); null (default) also allows catch-all and never-verified uploaded emails. Applies to enrollment only."
                  },
                  "validateEmailsBeforeSendEnabledAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ISO 8601 timestamp from which every email address is re-verified with ZeroBounce right before it is sent (and again once the last check is older than 14 days); addresses that come back invalid are skipped and marked invalid on the contact. Costs 2 credits per verified address. Null (default) sends without the check."
                  },
                  "dailyEmailLimit": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum emails this campaign sends per calendar day in its timezone, across all its mailboxes and excluding replies. Mailbox limits and sharing with other campaigns still apply. Null (default) means no campaign-level cap."
                  },
                  "dailyLinkedinConnectionLimit": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum LinkedIn connection requests this campaign sends per calendar day in its timezone, across all its LinkedIn accounts. Account limits still apply. Null (default) means no campaign-level cap."
                  },
                  "dailyLinkedinMessageLimit": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum LinkedIn messages (InMails included) this campaign sends per calendar day in its timezone, across all its LinkedIn accounts. Account limits still apply. Null (default) means no campaign-level cap."
                  },
                  "delegates": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse user id (24-character hex ObjectId) of a teammate, as the `id` of a GET /business/team/members row."
                    },
                    "description": "User ids of teammates allowed to view and edit this campaign in the app besides you; default []. Take each id from the `id` of a GET /business/team/members row (a row whose id is null has no linked user account and cannot be a delegate). Access is OR-joined — any one of the listed users gets it — and there is no cap on how many you list. Nothing checks the ids against your team on the way in, and the app's delegate test is a plain membership check on this array that runs ahead of every team rule, so an id belonging to any real Fuse user — teammate or not — grants that user the access the owner has: opening the campaign, editing its settings and steps, activating it so it sends, and seeing it in their own campaign list. Only a well-formed id that matches no user grants nobody anything. The grant stops at the app: every campaign endpoint here resolves the token owner's own campaigns, so a delegate calling with their own key still gets 404."
                  },
                  "campaignType": {
                    "type": "string",
                    "enum": [
                      "ai-generated",
                      "manual"
                    ],
                    "default": "manual",
                    "description": "manual (default): you write every step's subject/body and the draft is ready to author immediately. ai-generated: prompt analysis and topic generation run in the background; poll GET /business/campaigns/{campaignId} until initializationStatus is completed before editing or approving."
                  },
                  "templateId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Id of a saved campaign template (GET /business/campaign-templates) whose steps are copied into the new campaign; its channels replace the channels field, so the two cannot be combined. null means no template. An unknown or inaccessible template answers 404 TEMPLATE_NOT_FOUND."
                  },
                  "userPrompt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 5000,
                    "description": "ai-generated only: free-text brief (up to 5000 characters) describing the offer and goal; the AI analyses it to derive the campaign topics. Forbidden for manual campaigns."
                  },
                  "websiteUrls": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "maxLength": 2000,
                      "description": "An absolute http(s) URL (up to 2000 characters)."
                    },
                    "maxItems": 10,
                    "description": "ai-generated only: up to 10 URLs whose page content grounds the generated copy. Forbidden for manual campaigns."
                  },
                  "additionalInfo": {
                    "type": "string",
                    "maxLength": 10000,
                    "description": "ai-generated only: free text in your own words (up to 10000 characters) — product details, positioning, proof points; there is no fixed set of values. It is stored as one note on the knowledge profile built for this campaign, alongside websiteUrls, and grounds the generated copy. Forbidden for manual campaigns."
                  },
                  "ctaLink": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2000,
                    "description": "The campaign's call-to-action link, honoured for either campaign type; null or an empty string means no link. Accepted values: one absolute URL whose scheme is http:// or https:// (up to 2000 characters); anything else, a bare domain or a mailto: link included, is rejected. The URL is inserted verbatim wherever a step's text uses {CTA Link} or one of its aliases {Calendar Link}, {cta_link}, {calendar_link}, {{calendarLink}}."
                  },
                  "writingStyleId": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ai-generated only: id of one of your writing styles whose rules steer the generated copy; null or omitted uses your default style; an unknown id answers 404 WRITING_STYLE_NOT_FOUND. Forbidden for manual campaigns."
                  },
                  "knowledgeHubId": {
                    "type": "string",
                    "description": "ai-generated only: id of the knowledge hub (GET /business/knowledge-hubs) that grounds the generated content; omitted means your default hub; an unknown id answers 404 KNOWLEDGE_HUB_NOT_FOUND. Forbidden for manual campaigns."
                  }
                },
                "required": [
                  "campaignName"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listCampaigns",
        "summary": "List the token owner's campaigns with headline analytics",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1-100 (default 25).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "description": "Page size, 1-100 (default 25)."
            }
          },
          {
            "name": "pageNum",
            "in": "query",
            "required": false,
            "description": "1-based page number (default 1).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based page number (default 1)."
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Free text matched case-insensitively against the campaign name only (1-200 characters); any string is accepted. The value reaches the store as a regular expression rather than a literal, so metacharacters such as ( ) [ ] + * ? | are interpreted — send plain words, or escape them. A term that matches no campaign returns an empty page, not an error.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "description": "Free text matched case-insensitively against the campaign name only (1-200 characters); any string is accepted. The value reaches the store as a regular expression rather than a literal, so metacharacters such as ( ) [ ] + * ? | are interpreted — send plain words, or escape them. A term that matches no campaign returns an empty page, not an error."
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Restrict to ai-generated or manual campaigns — the same values a campaign's `type` reports.",
            "schema": {
              "type": "string",
              "enum": [
                "ai-generated",
                "manual"
              ],
              "description": "Restrict to ai-generated or manual campaigns — the same values a campaign's `type` reports."
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Restrict to one status: initializing (draft, not yet approved), active (approved and sending), stopped (stopped via /stop or deleted), paused_manual (paused by the app), initialization_failed (AI initialization failed; see initializationError).",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "initializing",
                "initialization_failed",
                "stopped",
                "paused_manual"
              ],
              "description": "Restrict to one status: initializing (draft, not yet approved), active (approved and sending), stopped (stopped via /stop or deleted), paused_manual (paused by the app), initialization_failed (AI initialization failed; see initializationError)."
            }
          },
          {
            "name": "folderId",
            "in": "query",
            "required": false,
            "description": "Return only campaigns filed in this sequences folder (see GET /business/folders).",
            "schema": {
              "type": "string",
              "description": "Return only campaigns filed in this sequences folder (see GET /business/folders)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaigns": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "initializing",
                              "active",
                              "stopped",
                              "paused_manual",
                              "initialization_failed",
                              null
                            ]
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "manual",
                              "ai-generated",
                              null
                            ]
                          },
                          "createdAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "startDate": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "When sending may start; null until the campaign has a start date."
                          },
                          "folderId": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Sequences folder the campaign is filed in, or null for the root."
                          },
                          "createdBy": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Display name of the campaign's owner."
                          },
                          "leadsStatus": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Enrollment progress of the source lists (for example not_started, in_progress, completed)."
                          },
                          "initializationError": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Our own status text when AI initialization failed."
                          },
                          "autoReply": {
                            "type": "boolean"
                          },
                          "isDynamic": {
                            "type": "boolean"
                          },
                          "channels": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "lists": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "name": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                }
                              },
                              "required": [
                                "id",
                                "name"
                              ]
                            }
                          },
                          "recipients": {
                            "type": "integer",
                            "description": "Contacts enrolled in the campaign."
                          },
                          "messagesSent": {
                            "type": "integer"
                          },
                          "completedActions": {
                            "type": "object",
                            "properties": {
                              "emails": {
                                "type": "integer"
                              },
                              "linkedinMessages": {
                                "type": "integer"
                              },
                              "linkedinInvites": {
                                "type": "integer"
                              },
                              "inmails": {
                                "type": "integer"
                              },
                              "profileVisits": {
                                "type": "integer"
                              },
                              "postsLiked": {
                                "type": "integer"
                              },
                              "callsMade": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "emails",
                              "linkedinMessages",
                              "linkedinInvites",
                              "inmails",
                              "profileVisits",
                              "postsLiked",
                              "callsMade"
                            ]
                          },
                          "opened": {
                            "type": "object",
                            "properties": {
                              "count": {
                                "type": "integer"
                              },
                              "rate": {
                                "type": "number",
                                "description": "Percentage of messages sent, 0-100."
                              }
                            },
                            "required": [
                              "count",
                              "rate"
                            ]
                          },
                          "clicked": {
                            "type": "object",
                            "properties": {
                              "count": {
                                "type": "integer"
                              },
                              "rate": {
                                "type": "number",
                                "description": "Percentage of messages sent, 0-100."
                              }
                            },
                            "required": [
                              "count",
                              "rate"
                            ]
                          },
                          "replied": {
                            "type": "object",
                            "properties": {
                              "count": {
                                "type": "integer"
                              },
                              "rate": {
                                "type": "number",
                                "description": "Percentage of messages sent, 0-100."
                              }
                            },
                            "required": [
                              "count",
                              "rate"
                            ]
                          },
                          "positiveReplied": {
                            "type": "object",
                            "properties": {
                              "count": {
                                "type": "integer"
                              },
                              "rate": {
                                "type": "number",
                                "description": "Percentage of messages sent, 0-100."
                              }
                            },
                            "required": [
                              "count",
                              "rate"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "status",
                          "type",
                          "createdAt",
                          "startDate",
                          "folderId",
                          "createdBy",
                          "leadsStatus",
                          "initializationError",
                          "autoReply",
                          "isDynamic",
                          "channels",
                          "lists",
                          "recipients",
                          "messagesSent",
                          "completedActions",
                          "opened",
                          "clicked",
                          "replied",
                          "positiveReplied"
                        ]
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "description": "1-based page number this response covers."
                        },
                        "pageSize": {
                          "type": "integer",
                          "description": "Rows requested per page."
                        },
                        "total": {
                          "type": "integer",
                          "description": "Total rows matching the query."
                        },
                        "totalPages": {
                          "type": "integer",
                          "description": "Total pages at this page size."
                        }
                      },
                      "required": [
                        "page",
                        "pageSize",
                        "total",
                        "totalPages"
                      ]
                    }
                  },
                  "required": [
                    "campaigns",
                    "pagination"
                  ]
                },
                "example": {
                  "campaigns": [
                    {
                      "id": "6a8da7718707dbcfb4448b96",
                      "name": "Q3 fintech outreach",
                      "status": "active",
                      "type": "manual",
                      "createdAt": "2026-08-25T14:32:17.586Z",
                      "startDate": "2026-08-26T00:00:00.000Z",
                      "folderId": null,
                      "createdBy": "Sofiia Hryshyna",
                      "leadsStatus": "completed",
                      "initializationError": null,
                      "autoReply": false,
                      "isDynamic": false,
                      "channels": [
                        "email"
                      ],
                      "lists": [
                        {
                          "id": "6a1edba88936e0fe1b20287c",
                          "name": "Fintech CFOs - US"
                        }
                      ],
                      "recipients": 9,
                      "messagesSent": 4,
                      "completedActions": {
                        "emails": 4,
                        "linkedinMessages": 0,
                        "linkedinInvites": 0,
                        "inmails": 0,
                        "profileVisits": 0,
                        "postsLiked": 0,
                        "callsMade": 0
                      },
                      "opened": {
                        "count": 3,
                        "rate": 75
                      },
                      "clicked": {
                        "count": 1,
                        "rate": 25
                      },
                      "replied": {
                        "count": 1,
                        "rate": 25
                      },
                      "positiveReplied": {
                        "count": 0,
                        "rate": 0
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "pageSize": 25,
                    "total": 210,
                    "totalPages": 9
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Lists the campaigns you own with their headline analytics, newest first. Campaigns delegated to you, and campaigns your team's visibility settings share with you, are NOT listed: every other endpoint in this family resolves the token owner's own campaigns only, so listing them would hand back ids that answer 404 everywhere else. `createdBy` is the campaign's owner and is therefore always the token owner. Deleted campaigns are never returned. Engagement rates are percentages of messages sent. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `422` `VALIDATION_FAILED` — A query parameter is out of range or not one of the accepted values; `param` names it.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}": {
      "get": {
        "operationId": "getCampaign",
        "summary": "Get a campaign's status",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaign": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The campaign's id."
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Display name."
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "manual",
                            "ai-generated",
                            null
                          ],
                          "description": "Which creation flow the campaign uses."
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "initializing",
                            "active",
                            "stopped",
                            "paused_manual",
                            "initialization_failed",
                            null
                          ],
                          "description": "Lifecycle status."
                        },
                        "initializationStatus": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "processing",
                            "completed",
                            "failed",
                            null
                          ],
                          "description": "Draft-preparation state. A manual campaign is completed from the start; an ai-generated one reaches completed when background topic generation finishes."
                        },
                        "initializationError": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Our own status text when initializationStatus is failed; null otherwise."
                        },
                        "listIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Ids of the lists the campaign sources contacts from."
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "type",
                        "status",
                        "initializationStatus",
                        "initializationError",
                        "listIds"
                      ]
                    }
                  },
                  "required": [
                    "campaign"
                  ]
                },
                "example": {
                  "campaign": {
                    "id": "6a8dc78c8d28fe4014b4e502",
                    "name": "Q3 fintech outreach",
                    "type": "manual",
                    "status": "initializing",
                    "initializationStatus": "completed",
                    "initializationError": null,
                    "listIds": [
                      "6a1edba88936e0fe1b20287c"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Returns one campaign's state. This is the poll an `ai-generated` campaign needs: creation returns immediately and the topic plan is written in the background, so watch `initializationStatus` reach `completed` before authoring steps or approving; `failed` puts the reason in `initializationError`. A `manual` campaign is `completed` from the start. Only the token owner's own campaigns resolve here (a delegated or team-visible campaign answers 404), and a deleted campaign answers 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      },
      "patch": {
        "operationId": "updateCampaign",
        "summary": "Update a campaign's settings",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaign": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The campaign's id."
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Display name."
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "manual",
                            "ai-generated",
                            null
                          ],
                          "description": "Which creation flow the campaign uses."
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "initializing",
                            "active",
                            "stopped",
                            "paused_manual",
                            "initialization_failed",
                            null
                          ],
                          "description": "Lifecycle status."
                        },
                        "initializationStatus": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "processing",
                            "completed",
                            "failed",
                            null
                          ],
                          "description": "Draft-preparation state. A manual campaign is completed from the start; an ai-generated one reaches completed when background topic generation finishes."
                        },
                        "initializationError": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Our own status text when initializationStatus is failed; null otherwise."
                        },
                        "listIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Ids of the lists the campaign sources contacts from."
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "type",
                        "status",
                        "initializationStatus",
                        "initializationError",
                        "listIds"
                      ]
                    }
                  },
                  "required": [
                    "campaign"
                  ]
                },
                "example": {
                  "campaign": {
                    "id": "6a8dd1205936d46e458ff40a",
                    "name": "Q3 fintech outreach (US)",
                    "type": "manual",
                    "status": "active",
                    "initializationStatus": "completed",
                    "initializationError": null,
                    "listIds": [
                      "6a1edba88936e0fe1b20287c"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Updates the campaign's shared settings block - name, start date, timezone and sending days, source and exclusion lists, enrollment exclusions, tracking, delegates and the {CTA Link} URL - and returns the campaign as stored. Every field is optional but at least one must be present. Changing `listIds` rewrites the source-list set; it does not by itself enroll a newly added list's contacts into a running campaign. Changing `campaignStartDate` reschedules the first step's still-pending sends, and changing `ctaLink` rewrites queued sends that carry the old link. Only the token owner's own campaigns can be updated: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `409` `CAMPAIGN_INITIALIZING` — listIds was sent while an ai-generated campaign's background initialization is still running, so its channels are not settled yet; poll GET /business/campaigns/{campaignId} until initializationStatus is completed or failed, then retry.\n- `422` `LIST_INCOMPATIBLE_WITH_CHANNELS` — The listIds together have no contact usable by the campaign's steps: they are empty, or no contact carries an email address (email/inmail step) or a LinkedIn URL (LinkedIn step).\n- `409` `CAMPAIGN_INITIALIZING` — listIds was sent while an ai-generated campaign's background initialization is still running, so its channels are not settled yet; poll GET /business/campaigns/{campaignId} until initializationStatus is completed or failed, then retry.\n- `422` `LIST_INCOMPATIBLE_WITH_CHANNELS` — The listIds together have no contact usable by the campaign's steps: they are empty, or no contact carries an email address (email/inmail step) or a LinkedIn URL (LinkedIn step).\n- `422` `EXCLUDE_COMPANY_LISTS_INVALID` — An excludeCompanyLists entry is not a non-archived company or people list owned by your team.\n- `422` `VALIDATION_FAILED` — Empty body, unknown key, an unrecognised timezone, a non-http(s) ctaLink, or a value out of range; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "campaignName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "New display name (1-200 characters, trimmed)."
                  },
                  "campaignStartDate": {
                    "type": "string",
                    "description": "New ISO 8601 start date-time; the first step's still-pending sends are rescheduled to it."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "New time zone in which the daily sending window and emailDays are evaluated. Accepted values are IANA time zone names, for example America/New_York, Europe/Berlin, Asia/Kolkata or UTC. Do not send an abbreviation: EST is in the tz database but resolves to a fixed UTC-5 zone that never observes daylight saving, so name the region instead. A name the tz database does not know is rejected rather than silently evaluated as UTC."
                  },
                  "emailDays": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "Monday",
                        "Tuesday",
                        "Wednesday",
                        "Thursday",
                        "Friday",
                        "Saturday",
                        "Sunday"
                      ],
                      "description": "An English weekday name with a capital first letter (Monday ... Sunday)."
                    },
                    "minItems": 1,
                    "description": "Replacement set of weekdays on which sends may go out. One of exactly: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday — capitalised English names, nothing else. The days are OR-joined: a send that comes due is pushed forward to the next day named in the set, so a weekday you leave out is never used. 1-7 unique names; naming all seven removes the weekday restriction."
                  },
                  "listIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse list id (24-character hex ObjectId), as the `id` of a GET /business/lists row."
                    },
                    "minItems": 1,
                    "maxItems": 10,
                    "description": "Replacement set of 1-10 source list ids; rewrites the campaign's source-list set but does not by itself enroll a newly added list's contacts into an already running campaign. Take the ids from GET /business/lists with entityType=contactList — a campaign enrolls contacts. The lists are OR-joined into a deduplicated union: they are read in the order given and a contact that sits in two of them is enrolled once, up to the campaign's 10000-contact cap, after which the remaining lists are skipped. This endpoint stores the ids without an ownership check (create answers 404 LIST_NOT_FOUND for one it cannot resolve), so an id that is not one of your lists is accepted here and simply contributes nobody. Like create, the lists together must have at least one contact with an enriched professional email for an email step and one with a LinkedIn profile for a LinkedIn step, else 422 LIST_INCOMPATIBLE_WITH_CHANNELS. The check reads the campaign's actual steps, so an ai-generated campaign whose initializationStatus is not yet completed or failed answers 409 CAMPAIGN_INITIALIZING; poll and retry."
                  },
                  "excludeLists": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse list id (24-character hex ObjectId), as the `id` of a GET /business/lists row."
                    },
                    "maxItems": 10,
                    "description": "Replacement set of up to 10 people-list ids whose members are excluded from future enrollment. Take the ids from GET /business/lists with entityType=contactList. The lists are OR-joined: a contact is skipped when it appears in any one of them, matched on contact id, email address (case-insensitively) or LinkedIn URL. These ids are stored without an ownership check, so an id that is not one of your lists is accepted and silently excludes nobody — and a companyList here excludes nobody either, use excludeCompanyLists for that."
                  },
                  "excludeCompanyLists": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse list id (24-character hex ObjectId), as the `id` of a GET /business/lists row."
                    },
                    "maxItems": 20,
                    "description": "Replacement set of up to 20 company or people list ids whose companies' contacts are skipped at enrollment. Take the ids from GET /business/lists — either entityType: a companyList contributes its companies, a contactList contributes the companies its contacts work at. The lists are OR-joined: a contact is skipped when its company appears in any one of them, matched by company id and by the company's web domain (personal-email domains are never used). Unlike excludeLists these ids are checked, so one that is unknown, archived or not your team's answers 422 EXCLUDE_COMPANY_LISTS_INVALID."
                  },
                  "excludeContacted": {
                    "type": "string",
                    "enum": [
                      "none",
                      "ever",
                      "last_1_month",
                      "last_3_months",
                      "last_6_months",
                      "last_1_year"
                    ],
                    "description": "Skips contacts your campaigns already reached: none keeps them, ever excludes anyone ever messaged, last_1_month / last_3_months / last_6_months / last_1_year exclude those messaged within that window; contacts with a pending send in an active campaign are always excluded. Applies to future enrollment only."
                  },
                  "excludeEngagedContacts": {
                    "type": "boolean",
                    "description": "When true, contacts who have already replied to one of your campaigns are excluded from enrollment. Applies to future enrollment only."
                  },
                  "isDynamic": {
                    "type": "boolean",
                    "description": "When true, contacts added to the source lists after activation are enrolled automatically by a background refresh."
                  },
                  "useLinkedinPosts": {
                    "type": "boolean",
                    "description": "When true, each contact's recent LinkedIn posts are fetched at activation and fed to AI personalization (needs a LinkedIn URL on the contact)."
                  },
                  "addUnsubscribeLink": {
                    "type": "boolean",
                    "description": "When true, every email step appends a one-click unsubscribe footer (email channel only)."
                  },
                  "openRateTrackingEnabledAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ISO 8601 timestamp from which the open-tracking pixel is added to outgoing emails, or null to switch open tracking off."
                  },
                  "sendOnlyToValidatedEmailsEnabledAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ISO 8601 timestamp from which enrollment only accepts contacts whose email verified as valid (catch-all and never-verified uploaded addresses skipped), or null to also allow both. Applies to future enrollment only."
                  },
                  "validateEmailsBeforeSendEnabledAt": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "ISO 8601 timestamp from which every email address is re-verified with ZeroBounce right before it is sent (2 credits per verified address; invalid addresses are skipped and marked invalid on the contact), or null to send without the check."
                  },
                  "dailyEmailLimit": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum emails this campaign sends per calendar day in its timezone, across all its mailboxes and excluding replies. Mailbox limits and sharing with other campaigns still apply. Pass null to remove the cap."
                  },
                  "dailyLinkedinConnectionLimit": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum LinkedIn connection requests this campaign sends per calendar day in its timezone, across all its LinkedIn accounts. Account limits still apply. Pass null to remove the cap."
                  },
                  "dailyLinkedinMessageLimit": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum LinkedIn messages (InMails included) this campaign sends per calendar day in its timezone, across all its LinkedIn accounts. Account limits still apply. Pass null to remove the cap."
                  },
                  "delegates": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A Fuse user id (24-character hex ObjectId) of a teammate, as the `id` of a GET /business/team/members row."
                    },
                    "description": "Replacement list of teammate user ids allowed to view and edit this campaign in the app; [] revokes every delegate. Take each id from the `id` of a GET /business/team/members row (a row whose id is null has no linked user account and cannot be a delegate). Access is OR-joined — any one of the listed users gets it — and there is no cap on how many you list. Nothing checks the ids against your team on the way in, and the app's delegate test is a plain membership check on this array that runs ahead of every team rule, so an id belonging to any real Fuse user — teammate or not — grants that user the access the owner has: opening the campaign, editing its settings and steps, activating it so it sends, and seeing it in their own campaign list. Only a well-formed id that matches no user grants nobody anything. The grant stops at the app: every campaign endpoint here resolves the token owner's own campaigns, so a delegate calling with their own key still gets 404."
                  },
                  "ctaLink": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "maxLength": 2000,
                    "description": "New call-to-action link, or null / an empty string to clear it; queued sends that already carry the old link are rewritten to the new one. Accepted values: one absolute URL whose scheme is http:// or https:// (up to 2000 characters); anything else, a bare domain or a mailto: link included, is rejected. The URL is inserted verbatim wherever a step's text uses {CTA Link} or one of its aliases {Calendar Link}, {cta_link}, {calendar_link}, {{calendarLink}}."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteCampaign",
        "summary": "Stop and delete a campaign",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Stops the campaign and deletes it. This is a soft delete: sending halts immediately, open task mirrors are cleared, and the campaign disappears from GET /business/campaigns and from GET /business/campaigns/{campaignId}. Contacts keep their per-contact state, and sends already delivered are unaffected. Deleting a campaign that is already deleted answers 404, like every other endpoint here: once deleted, a campaign does not exist on this surface. Only the token owner's own campaigns can be deleted. Rate limit: this endpoint and POST /business/campaigns/{campaignId}/stop share a tighter cap of 10 requests/minute and 100/day, applied inside the shared campaigns bucket of 30 requests/minute and 1,000/day per token owner (shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint).\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `409` `CAMPAIGN_BUSY` — Another approve or stop is holding this campaign's activation lock. Retry in a few seconds.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Either this endpoint's own cap (10 requests/minute, 100/day) or the shared campaigns bucket (30/minute, 1,000/day for this token owner, shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call) was exceeded. The RateLimit-* headers on the response describe the shared bucket, so a refusal from this endpoint's own cap can still report requests remaining and carries no Retry-After.\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/steps": {
      "get": {
        "operationId": "listCampaignSteps",
        "summary": "List a campaign's sequence steps",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "steps": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "channel": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "email",
                              "linkedin_connection",
                              "linkedin_message",
                              "linkedin_visit",
                              "linkedin_like",
                              "inmail",
                              "dialer",
                              "todo",
                              null
                            ]
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "manual",
                              "ai_generated",
                              "ai_reply",
                              null
                            ],
                            "description": "How the step's message is produced."
                          },
                          "sequenceNumber": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "0-based slot in the sequence."
                          },
                          "daysBetween": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "Whole days to wait after the previous step."
                          },
                          "title": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Editor label; set from the subject on a manual step and generated with the topic on an AI step."
                          },
                          "topic": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Brief an AI step writes each message from; null on an unwritten manual step."
                          },
                          "subject": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Manual subject line; null when the step has no template yet or is AI-written."
                          },
                          "body": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Manual message body; null when the step has no template yet or is AI-written."
                          },
                          "cc": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Addresses copied on every send of this step (email only)."
                          }
                        },
                        "required": [
                          "id",
                          "channel",
                          "type",
                          "sequenceNumber",
                          "daysBetween",
                          "title",
                          "topic",
                          "subject",
                          "body",
                          "cc"
                        ]
                      }
                    }
                  },
                  "required": [
                    "steps"
                  ]
                },
                "example": {
                  "steps": [
                    {
                      "id": "6a8dc78d8d28fe4014b4e507",
                      "channel": "email",
                      "type": "manual",
                      "sequenceNumber": 0,
                      "daysBetween": 0,
                      "title": null,
                      "topic": null,
                      "subject": null,
                      "body": null,
                      "cc": []
                    },
                    {
                      "id": "6a8dce2ef83628aea1088041",
                      "channel": "email",
                      "type": "manual",
                      "sequenceNumber": 1,
                      "daysBetween": 2,
                      "title": "probe step subject",
                      "topic": null,
                      "subject": "Following up on BrightPay's finance hiring",
                      "body": "<p>Hi {Contact First Name}, circling back on my note last week.</p>",
                      "cc": [
                        "ops@yourcompany.com"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Lists the campaign's sequence steps in `sequenceNumber` order (0-based). A campaign created through this API starts with one empty step per requested channel, so this is how you discover the ids to write content into with PATCH /business/campaigns/{campaignId}/steps/{stepId}. `type` tells you what to write: `manual` needs `subject` and `body`, `ai_generated` and `ai_reply` write from `topic`. Only the token owner's own campaigns resolve here. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      },
      "post": {
        "operationId": "createCampaignStep",
        "summary": "Add a sequence step",
        "tags": [
          "Campaign steps"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "step": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "channel": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "email",
                            "linkedin_connection",
                            "linkedin_message",
                            "linkedin_visit",
                            "linkedin_like",
                            "inmail",
                            "dialer",
                            "todo",
                            null
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "manual",
                            "ai_generated",
                            "ai_reply",
                            null
                          ],
                          "description": "How the step's message is produced."
                        },
                        "sequenceNumber": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "0-based slot in the sequence."
                        },
                        "daysBetween": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Whole days to wait after the previous step."
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Editor label; set from the subject on a manual step and generated with the topic on an AI step."
                        },
                        "topic": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Brief an AI step writes each message from; null on an unwritten manual step."
                        },
                        "subject": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Manual subject line; null when the step has no template yet or is AI-written."
                        },
                        "body": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Manual message body; null when the step has no template yet or is AI-written."
                        },
                        "cc": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Addresses copied on every send of this step (email only)."
                        }
                      },
                      "required": [
                        "id",
                        "channel",
                        "type",
                        "sequenceNumber",
                        "daysBetween",
                        "title",
                        "topic",
                        "subject",
                        "body",
                        "cc"
                      ]
                    }
                  },
                  "required": [
                    "step"
                  ]
                },
                "example": {
                  "step": {
                    "id": "6a8dce2ef83628aea1088041",
                    "channel": "email",
                    "type": "manual",
                    "sequenceNumber": 1,
                    "daysBetween": 2,
                    "title": "probe step subject",
                    "topic": null,
                    "subject": "Following up on BrightPay's finance hiring",
                    "body": "<p>Hi {Contact First Name}, circling back on my note last week.</p>",
                    "cc": [
                      "ops@yourcompany.com"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Adds one sequence step. `sequenceNumber` is the step's 0-based slot - the same numbering GET /business/campaigns/{campaignId}/steps reports - and must be free (409 STEP_POSITION_TAKEN); existing steps are not shifted on insert, and only DELETE renumbers. `daysBetween` is the wait after the previous step (after the campaign start for step 0). `type: manual` sends your `subject`/`body` as written, with {Variable} tokens and spintax substituted per lead at send time; `type: ai_generated` writes its own topic and title with AI when the step is created and renders each message per lead (do not send `topic`); `type: ai_reply` drafts a reply from the `topic` you supply and parks it for approval. `linkedin_visit` and `linkedin_like` steps carry no message at all. A `linkedin_connection` step may not follow a `linkedin_message` step (422 STEP_ORDER_INVALID). Only the token owner may add steps. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `409` `STEP_POSITION_TAKEN` — A step already occupies this sequenceNumber in the campaign.\n- `422` `STEP_ORDER_INVALID` — A linkedin_connection step would follow a linkedin_message step.\n- `422` `VALIDATION_FAILED` — Unknown key, missing channel/sequenceNumber/daysBetween, a value out of range, a topic on an ai_generated step, a missing topic on an ai_reply step, or content on a linkedin_visit / linkedin_like step; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — The step could not be stored, or AI topic generation failed for an ai_generated step.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "channel": {
                    "type": "string",
                    "enum": [
                      "email",
                      "linkedin_connection",
                      "linkedin_message",
                      "linkedin_visit",
                      "linkedin_like",
                      "inmail",
                      "dialer",
                      "todo"
                    ],
                    "description": "Step channel: email, linkedin_connection (connection request), linkedin_message (message to an accepted connection), linkedin_visit (profile visit, no content), linkedin_like (reaction to a recent post, no content), inmail (LinkedIn InMail, consumes InMail credits), dialer (phone-call task for a rep) or todo (free-form human task). A linkedin_connection step cannot come after a linkedin_message step (422 STEP_ORDER_INVALID)."
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "manual",
                      "ai_generated",
                      "ai_reply"
                    ],
                    "default": "manual",
                    "description": "manual (default) sends your subject/body as written; ai_generated writes a topic and title with AI at creation and renders each message per lead at send time (send no topic — it is generated); ai_reply is an AI-drafted reply that waits for approval and needs a topic."
                  },
                  "sequenceNumber": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 50,
                    "description": "The step's 0-based slot in the sequence — the same numbering GET /business/campaigns/{campaignId}/steps reports, so 0 is the first step. Must be unused in this campaign (409 STEP_POSITION_TAKEN); existing steps are not shifted on insert (only DELETE renumbers)."
                  },
                  "daysBetween": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 90,
                    "description": "Whole days to wait after the previous step (or after the campaign start for the first step) before this one is due, 0-90."
                  },
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Subject line for a manual step (up to 500 characters, may be empty); becomes the step title. Rejected on linkedin_visit and linkedin_like steps, which carry no message."
                  },
                  "body": {
                    "description": "Message body for a manual step (up to 20000 characters; {Variable} tokens and spintax substitute at send time). On a linkedin_connection step this is the invitation note, capped at LinkedIn's 200-character limit. Rejected on linkedin_visit and linkedin_like steps, which carry no message."
                  },
                  "topic": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500,
                    "description": "Free text: what this step should say, in your own words — there is no fixed set of topics. 1-500 characters. Required for ai_reply, rejected for ai_generated (which generates its own) and for linkedin_visit / linkedin_like steps. Stored but not rendered on a manual step."
                  },
                  "cc": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "email",
                      "maxLength": 320,
                      "description": "A bare email address, up to 320 characters."
                    },
                    "maxItems": 10,
                    "description": "Accepted values: bare email addresses such as ops@example.com — a display name or angle brackets is rejected, up to 320 characters each. Every address you list is copied on every send of this step, up to 10 addresses. Only an email step actually sends them: on any other channel the value is stored and never used."
                  }
                },
                "required": [
                  "channel",
                  "sequenceNumber",
                  "daysBetween"
                ]
              }
            }
          }
        }
      }
    },
    "/business/campaigns/{campaignId}/steps/{stepId}": {
      "patch": {
        "operationId": "updateCampaignStep",
        "summary": "Edit a sequence step",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          },
          {
            "name": "stepId",
            "in": "path",
            "required": true,
            "description": "The sequence step's id, as returned by GET /business/campaigns/{campaignId}/steps (24-character hex ObjectId).",
            "schema": {
              "type": "string",
              "description": "The sequence step's id, as returned by GET /business/campaigns/{campaignId}/steps (24-character hex ObjectId)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stepId": {
                      "type": "string",
                      "description": "The step that was updated."
                    }
                  },
                  "required": [
                    "stepId"
                  ]
                },
                "example": {
                  "stepId": "6a8dce2ef83628aea1088041"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Writes one sequence step's content. Send `subject` and `body` together for a manual step (the pair replaces the step's whole template), `topic` for an `ai_generated` or `ai_reply` step - setting a topic also regenerates the step's title with AI - and `daysBetween` to change the wait before the step. At least one field must be present. A manual campaign cannot be approved until every step has a subject and body, which is what makes this endpoint the missing piece for a machine caller. Only the token owner may edit steps. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `404` `SEQUENCE_STEP_NOT_FOUND` — No step with this id belongs to this campaign.\n- `422` `CONNECTION_NOTE_TOO_LONG` — The step is a linkedin_connection, whose body is the invitation note LinkedIn caps at 200 characters, and the body sent is longer.\n- `422` `VALIDATION_FAILED` — Empty body, unknown key, subject without body (or the reverse), or a value out of range; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "New subject line for a manual step (up to 500 characters, may be empty); must be sent together with body because the pair replaces the step's whole template. Silently ignored on ai_generated / ai_reply steps."
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 50000,
                    "description": "New message body for a manual step (up to 50000 characters, may be empty; HTML is allowed on email steps, {Variable} tokens and spintax substitute at send time); must be sent together with subject. On a linkedin_connection step this is the invitation note LinkedIn caps at 200 characters — a longer body answers 422 CONNECTION_NOTE_TOO_LONG. Silently ignored on ai_generated / ai_reply steps."
                  },
                  "topic": {
                    "type": "string",
                    "maxLength": 1000,
                    "description": "Free text: what this step should say, in your own words — there is no fixed set of topics. Up to 1000 characters. An AI step writes each message from it, and setting it also regenerates the step's title with AI. Stored but not rendered for manual steps."
                  },
                  "daysBetween": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 365,
                    "description": "Whole days to wait after the previous step (or after the campaign start for the first step) before this step is due, 0-365."
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteCampaignStep",
        "summary": "Remove a sequence step",
        "tags": [
          "Campaign steps"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          },
          {
            "name": "stepId",
            "in": "path",
            "required": true,
            "description": "The sequence step's id, as returned by GET /business/campaigns/{campaignId}/steps (24-character hex ObjectId).",
            "schema": {
              "type": "string",
              "description": "The sequence step's id, as returned by GET /business/campaigns/{campaignId}/steps (24-character hex ObjectId)."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Removes one sequence step. The remaining steps are renumbered so `sequenceNumber` stays contiguous from 0, which is the only operation that shifts existing steps. Queued sends already created for the removed step are not retro-actively deleted. Only the token owner may delete steps. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `404` `SEQUENCE_STEP_NOT_FOUND` — No step with this id belongs to this campaign.\n- `422` `VALIDATION_FAILED` — campaignId or stepId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/approve": {
      "post": {
        "operationId": "approveCampaign",
        "summary": "Approve (activate) a draft campaign",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaignId": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "description": "The campaign's status once activation was accepted."
                    }
                  },
                  "required": [
                    "campaignId",
                    "status"
                  ]
                },
                "example": {
                  "campaignId": "6a8da7718707dbcfb4448b96",
                  "status": "active"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Approves (activates) a draft campaign so the scheduler starts sending. Validation is synchronous - the campaign must have a source list, and every step must carry the content its type needs - and activation itself then runs in the background, which is why this answers 202. Re-approving a stopped campaign resumes it with its parked rows intact. This is the only endpoint in the family that causes messages to be sent. Ownership is required: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404 without approving anything. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `409` `CAMPAIGN_NOT_APPROVABLE` — The campaign is not in a state that can be activated (for example it is already active).\n- `409` `CAMPAIGN_BUSY` — Another approve or stop is holding this campaign's activation lock. Retry in a few seconds.\n- `422` `CAMPAIGN_NOT_READY` — The campaign is missing something activation requires: no source list, a step with no content, a missing subject/body or topic, or no connected email / LinkedIn account for one of its channels.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/knowledge-hubs": {
      "get": {
        "operationId": "listKnowledgeHubs",
        "summary": "List the token owner's knowledge hubs",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "knowledgeHubs"
                  ],
                  "properties": {
                    "knowledgeHubs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "companyName",
                          "status",
                          "isDefault",
                          "createdAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "24-character hex id of the hub."
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Hub name; the placeholder \"Processing...\" while a hub created without a name is still building."
                          },
                          "companyName": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Company name derived from the crawled content; null until the build finishes."
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "processing",
                              "complete",
                              "draft",
                              null
                            ],
                            "description": "processing = the crawl and page synthesis are running, complete = the hub is usable, draft = the hub is not built — either it was saved as a draft in the web app and never built, or its last build exhausted its retries, null = a hub the platform created automatically for a campaign."
                          },
                          "isDefault": {
                            "type": "boolean",
                            "description": "Whether this is the default hub used when a campaign names none."
                          },
                          "createdAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "knowledgeHubs": [
                    {
                      "id": "68a1f8509c41d20014b3ee41",
                      "name": "Brightpay KB",
                      "companyName": "Brightpay",
                      "status": "complete",
                      "isDefault": true,
                      "createdAt": "2026-06-01T12:00:00.000Z"
                    },
                    {
                      "id": "68a1f8509c41d20014b3ee42",
                      "name": "Processing...",
                      "companyName": null,
                      "status": "processing",
                      "isDefault": false,
                      "createdAt": "2026-08-20T09:15:00.000Z"
                    },
                    {
                      "id": "688c9457c4a2e7b424d92981",
                      "name": "Campaign: LinkedIn Campaign - Aug 1, 2025",
                      "companyName": null,
                      "status": null,
                      "isDefault": false,
                      "createdAt": "2025-08-01T10:17:59.260Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Knowledge hubs ground AI campaign generation in your company's content. Pass a hub's `id` as `knowledgeHubId` when creating an AI campaign, or mark one hub as the default. Returns every hub you own (deleted hubs excluded), default hub first and then newest first; there is no pagination. `status` is `processing` while the crawl and page synthesis run, `complete` once the hub is usable, `draft` when the hub is not built (it was saved as a draft in the web app and never built, or its last build exhausted its retries), and null for hubs the platform created automatically for a campaign. A `draft` hub is not usable for grounding, and one that never produced a knowledge store is refused by the endpoints that need one. Grounding a campaign on a `processing` hub yields thinner content than waiting for `complete`. Hub builds and reads do not debit credits. Shares the campaigns rate bucket (30 requests per minute, 1000 per day).\n\nErrors:\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      },
      "post": {
        "operationId": "createKnowledgeHub",
        "summary": "Create a knowledge hub from websites",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "knowledgeHub"
                  ],
                  "properties": {
                    "knowledgeHub": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "companyName",
                        "status",
                        "isDefault",
                        "websites",
                        "notes",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The name you sent, or the placeholder \"Processing...\" until the build generates one."
                        },
                        "companyName": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Always null on creation; filled in by the build."
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "processing",
                            "complete",
                            "draft",
                            null
                          ],
                          "description": "processing = the crawl and page synthesis are running, complete = the hub is usable, draft = the hub is not built — either it was saved as a draft in the web app and never built, or its last build exhausted its retries."
                        },
                        "isDefault": {
                          "type": "boolean"
                        },
                        "websites": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "url",
                              "includeSubPages",
                              "isCompetitor",
                              "parentUrl",
                              "lastCrawledAt"
                            ],
                            "properties": {
                              "url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "includeSubPages": {
                                "type": "boolean",
                                "description": "Whether the site's subpages were expanded when it was added."
                              },
                              "isCompetitor": {
                                "type": "boolean"
                              },
                              "parentUrl": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Set on subpages the crawler discovered: the website they were collected from. null on a website you added yourself."
                              },
                              "lastCrawledAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time",
                                "description": "When this URL was last successfully crawled; null if it has never been crawled."
                              }
                            }
                          },
                          "description": "The websites you added plus the subpages the crawler discovered from them (subpages carry parentUrl)."
                        },
                        "notes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "text",
                              "filename",
                              "isCompetitor",
                              "hasAttachment"
                            ],
                            "properties": {
                              "id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Note id; the attachment endpoints address notes by it."
                              },
                              "text": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "filename": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Label the note is cited by, and the key notes are merged on when the hub is updated."
                              },
                              "isCompetitor": {
                                "type": "boolean"
                              },
                              "hasAttachment": {
                                "type": "boolean",
                                "description": "Always false on creation — attach documents once the hub exists."
                              }
                            }
                          }
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "knowledgeHub": {
                    "id": "68a1f8509c41d20014b3ee41",
                    "name": "Brightpay KB",
                    "companyName": null,
                    "status": "processing",
                    "isDefault": false,
                    "websites": [
                      {
                        "url": "https://brightpay.com",
                        "includeSubPages": true,
                        "isCompetitor": false,
                        "parentUrl": null,
                        "lastCrawledAt": null
                      }
                    ],
                    "notes": [
                      {
                        "id": "68a1f8509c41d20014b3ee55",
                        "text": "We sell payroll software to UK accountants.",
                        "filename": "positioning.md",
                        "isCompetitor": false,
                        "hasAttachment": false
                      }
                    ],
                    "createdAt": "2026-08-20T09:15:00.000Z",
                    "updatedAt": "2026-08-20T09:15:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates the hub immediately with `status` `processing` and enqueues the build: every website is crawled (subpages too where `includeSubPages` is true), the content is synthesized into knowledge pages, and a company name — and, when `name` was omitted, the hub name — are generated. Poll `GET /business/knowledge-hubs/{hubId}` until `status` is `complete`; `draft` means the build did not finish — it exhausted its retries (hubs saved as drafts in the web app carry the same status without ever having been built). Until the build finishes a hub created without a name carries the placeholder \"Processing...\", and `websites` lists only what you sent — the crawler's subpages appear later. Building does not debit credits. Inline file attachments are not accepted here: add them per note via `POST /business/knowledge-hubs/{hubId}/attachments` once the hub is `complete`. `isDefault: true` makes this the default hub and clears the flag on the previous one.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The body failed validation locally, or a website URL the crawler cannot parse was rejected by the builder.\n- `500` `UNEXPECTED_ERROR` — The build workflow could not be enqueued (upstream STATE_MACHINE_ERROR); no hub was created — retry.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "Hub name (1-100 characters); omit to have one generated from the crawled content once the build finishes."
                  },
                  "websites": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "minLength": 4,
                          "maxLength": 2048,
                          "description": "Website to crawl (4-2048 characters), with or without the scheme, e.g. brightpay.com or https://brightpay.com/pricing; an unparseable URL answers 422 VALIDATION_FAILED."
                        },
                        "includeSubPages": {
                          "type": "boolean",
                          "default": false,
                          "description": "Also crawl the site's subpages (up to 100 per crawl; a re-crawl skips subpages the hub already stores and keeps only the newly found ones); default false."
                        },
                        "isCompetitor": {
                          "type": "boolean",
                          "default": false,
                          "description": "Treat the site as a competitor: its content feeds competitor pages instead of the company's own profile; default false."
                        }
                      },
                      "required": [
                        "url"
                      ],
                      "description": "One website the hub is built from."
                    },
                    "minItems": 1,
                    "maxItems": 20,
                    "description": "Websites the hub is built from: at least 1, at most 20. Accepted values for each entry's url: any http(s) web address, with or without the scheme (brightpay.com, https://brightpay.com/pricing). Every entry is crawled and all of the collected text is pooled into ONE set of knowledge pages — entries are not kept apart, and a page reached from two entries is used once. The crawl runs in the background after the 202, so a site that cannot be fetched is never reported as an error: its entry stays on the hub with lastCrawledAt null and contributes nothing. Read the hub back to check."
                  },
                  "notes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 60000,
                          "description": "Free-text knowledge to include (1-60,000 characters), e.g. positioning, objection handling, internal docs."
                        },
                        "filename": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 255,
                          "description": "Label the note is cited by in generated pages, and the key a later PATCH merges this note on (1-255 characters). Free text; omit it and the note is filed under the literal \"Internal Document\". Give every note a distinct value: notes that share one (two notes without a filename share the default) are all stored, but only the first is read when the hub's pages are generated — the rest contribute nothing and no error is returned."
                        },
                        "isCompetitor": {
                          "type": "boolean",
                          "default": false,
                          "description": "Treat the note as competitor material rather than the company's own; default false."
                        }
                      },
                      "required": [
                        "text"
                      ],
                      "description": "One free-text note; attach a document to it afterwards via POST /business/knowledge-hubs/{hubId}/attachments."
                    },
                    "maxItems": 50,
                    "description": "Free-text notes to include as sources (up to 50). Inline file uploads are not accepted here."
                  },
                  "isDefault": {
                    "type": "boolean",
                    "default": false,
                    "description": "Make this hub the default one used when a campaign does not name a hub; the previous default is unset. Default false."
                  }
                },
                "required": [
                  "websites"
                ]
              }
            }
          }
        }
      }
    },
    "/business/knowledge-hubs/default": {
      "post": {
        "operationId": "setDefaultKnowledgeHub",
        "summary": "Make a hub the default one",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "knowledgeHub"
                  ],
                  "properties": {
                    "knowledgeHub": {
                      "type": "object",
                      "required": [
                        "id",
                        "isDefault"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "isDefault": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "knowledgeHub": {
                    "id": "68a1f8509c41d20014b3ee41",
                    "isDefault": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Marks one of your own hubs as the default one — the hub used when a campaign is created without a `knowledgeHubId` — and clears the flag on every other hub you own. A teammate's hub is readable through `GET /business/knowledge-hubs/{hubId}` but cannot be made your default and answers 403 `KNOWLEDGE_HUB_OWNER_ONLY`. The response echoes the request; read the hub back with `GET /business/knowledge-hubs/{hubId}` to confirm.\n\nErrors:\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — The hub belongs to a teammate; you can read it, but only its owner can make it their default hub.\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `422` `VALIDATION_FAILED` — hubId missing or not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "hubId": {
                    "type": "string",
                    "description": "24-character hex id of the hub to make the default; every other hub loses the flag."
                  }
                },
                "required": [
                  "hubId"
                ]
              }
            }
          }
        }
      }
    },
    "/business/knowledge-hubs/learned-facts": {
      "get": {
        "operationId": "listLearnedFacts",
        "summary": "Facts learned from the team's communications",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "facts"
                  ],
                  "properties": {
                    "facts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "claim",
                          "category",
                          "confidence",
                          "channels",
                          "sourceCount",
                          "asOf",
                          "isOwn",
                          "createdAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "claim": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The anonymized fact text."
                          },
                          "category": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "overview",
                              "products",
                              "pricing",
                              "icp-use-cases",
                              "differentiators",
                              "competitors",
                              "faq",
                              "source-digest",
                              "custom",
                              "objection",
                              "faq-insight",
                              null
                            ]
                          },
                          "confidence": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "minimum": 0,
                            "maximum": 1
                          },
                          "channels": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "email",
                                "linkedin",
                                "transcript",
                                "call"
                              ]
                            },
                            "description": "Communication types the fact was learned from."
                          },
                          "sourceCount": {
                            "type": "integer",
                            "description": "How many communications back the fact."
                          },
                          "asOf": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "Date of the most recent supporting communication; falls back to the extraction time."
                          },
                          "isOwn": {
                            "type": "boolean",
                            "description": "Whether the fact came from your own communications rather than a teammate's."
                          },
                          "createdAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "facts": [
                    {
                      "id": "68a1fb0a9c41d20014b3f201",
                      "claim": "Prospects frequently ask whether a SOC 2 report is available before a trial.",
                      "category": "faq-insight",
                      "confidence": 0.9,
                      "channels": [
                        "email",
                        "call"
                      ],
                      "sourceCount": 3,
                      "asOf": "2026-08-12T05:02:46.934Z",
                      "isOwn": true,
                      "createdAt": "2026-08-13T05:02:46.934Z"
                    },
                    {
                      "id": "68a1fb0a9c41d20014b3f202",
                      "claim": "Buyers compare the product against legacy prospecting databases on data freshness.",
                      "category": "competitors",
                      "confidence": 1,
                      "channels": [
                        "linkedin"
                      ],
                      "sourceCount": 1,
                      "asOf": "2026-07-19T17:13:05.426Z",
                      "isOwn": false,
                      "createdAt": "2026-07-24T05:02:46.934Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Anonymized facts the platform extracted from your team's sent emails, LinkedIn messages, calls and meeting transcripts — the same set that hubs with learning enabled fold into their pages on the daily learning run. Team-scoped (every teammate's active facts, across all hubs), sorted by category then newest first, with no pagination. `confidence` runs 0-1, `channels` names the communication types the fact was learned from, `sourceCount` how many communications back it, `asOf` the most recent of those, and `isOwn` whether the fact came from your own communications. Correct a fact with PATCH or retire it with DELETE; either takes effect in the hubs on the next daily run.\n\nErrors:\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/knowledge-hubs/learned-facts/{factId}": {
      "patch": {
        "operationId": "updateLearnedFact",
        "summary": "Correct a learned fact",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "factId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the learned fact (from GET /business/knowledge-hubs/learned-facts).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the learned fact (from GET /business/knowledge-hubs/learned-facts)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "fact"
                  ],
                  "properties": {
                    "fact": {
                      "type": "object",
                      "required": [
                        "id",
                        "claim",
                        "category"
                      ],
                      "description": "The fields the update reports. Read the fact back from the list endpoint for the rest.",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "claim": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The claim as stored after this call."
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "overview",
                            "products",
                            "pricing",
                            "icp-use-cases",
                            "differentiators",
                            "competitors",
                            "faq",
                            "source-digest",
                            "custom",
                            "objection",
                            "faq-insight",
                            null
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "fact": {
                    "id": "68a1fb0a9c41d20014b3f201",
                    "claim": "A SOC 2 Type II report is available on request before a trial.",
                    "category": "faq-insight"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Corrects a learned fact's claim text and/or category. Any member of the owning teammate's team may edit. A new claim must stay anonymized — no person or customer names, no contract-level details — or the call answers 422 `LEARNED_FACT_NOT_ANONYMIZED`. The correction reaches the hubs' pages on the next daily learning run. The response carries only the fields this call changes; read the fact back from `GET /business/knowledge-hubs/learned-facts` for its confidence, channels and dates. Retired facts cannot be edited (404).\n\nErrors:\n- `404` `LEARNED_FACT_NOT_FOUND` — No active fact with that id, it was already retired, or it belongs to another team (existence is never confirmed).\n- `422` `LEARNED_FACT_NOT_ANONYMIZED` — The new claim names a person or customer, or carries a contract-level detail.\n- `422` `VALIDATION_FAILED` — Neither claim nor category given, or a value outside its limits or enum.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "claim": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "Corrected claim text (1-1000 characters). Free text — there is no vocabulary — but it must stay anonymized: a deterministic gate answers 422 LEARNED_FACT_NOT_ANONYMIZED when the claim contains an email address, a run of 9 or more phone-like digits, a currency amount in the same claim as deal language (discount, quote, contract, renewal, proposal, negotiated, agreed), or contract vocabulary (renewal date, contract term, termination clause, auto-renew, payment terms, net 30/60/90, master service agreement, MSA, SOW, non-disclosure, NDA). Person and customer names are NOT checked, so keep them out yourself. The edit reaches the hub's pages on the next daily learning run, not immediately."
                  },
                  "category": {
                    "type": "string",
                    "enum": [
                      "overview",
                      "products",
                      "pricing",
                      "icp-use-cases",
                      "differentiators",
                      "competitors",
                      "faq",
                      "source-digest",
                      "custom",
                      "objection",
                      "faq-insight"
                    ],
                    "description": "Fact category, one of overview (company summary), products, pricing, icp-use-cases (ideal customers and use cases), differentiators, competitors, faq, source-digest (digest of one source), custom (user-authored), objection (a buyer objection) or faq-insight (a recurring question)."
                  }
                },
                "description": "At least one of claim or category is required."
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteLearnedFact",
        "summary": "Discard a learned fact",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "factId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the learned fact (from GET /business/knowledge-hubs/learned-facts).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the learned fact (from GET /business/knowledge-hubs/learned-facts)."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Retires a learned fact so it stops feeding the team's hubs. Any member of the owning teammate's team may retire a fact. The removal is soft (the fact is marked superseded, keeping its audit trail) and cascades out of the hubs' pages on the next daily learning run. Retiring an already retired fact answers 404.\n\nErrors:\n- `404` `LEARNED_FACT_NOT_FOUND` — No active fact with that id, it was already retired, or it belongs to another team.\n- `422` `VALIDATION_FAILED` — factId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/knowledge-hubs/{hubId}": {
      "get": {
        "operationId": "getKnowledgeHub",
        "summary": "A hub's full detail",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "knowledgeHub"
                  ],
                  "properties": {
                    "knowledgeHub": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "companyName",
                        "status",
                        "isDefault",
                        "websites",
                        "notes",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Hub name; the placeholder \"Processing...\" while a hub created without a name is still building."
                        },
                        "companyName": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Company name derived from the crawled content; null until the build finishes."
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "processing",
                            "complete",
                            "draft",
                            null
                          ],
                          "description": "processing = the crawl and page synthesis are running, complete = the hub is usable, draft = the hub is not built — either it was saved as a draft in the web app and never built, or its last build exhausted its retries, null = a hub the platform created automatically for a campaign."
                        },
                        "isDefault": {
                          "type": "boolean"
                        },
                        "websites": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "url",
                              "includeSubPages",
                              "isCompetitor",
                              "parentUrl",
                              "lastCrawledAt"
                            ],
                            "properties": {
                              "url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "includeSubPages": {
                                "type": "boolean",
                                "description": "Whether the site's subpages were expanded when it was added."
                              },
                              "isCompetitor": {
                                "type": "boolean"
                              },
                              "parentUrl": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Set on subpages the crawler discovered: the website they were collected from. null on a website you added yourself."
                              },
                              "lastCrawledAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time",
                                "description": "When this URL was last successfully crawled; null if it has never been crawled."
                              }
                            }
                          },
                          "description": "The websites you added plus the subpages the crawler discovered from them (subpages carry parentUrl)."
                        },
                        "notes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "text",
                              "filename",
                              "isCompetitor",
                              "hasAttachment"
                            ],
                            "properties": {
                              "id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Note id; the attachment endpoints address notes by it."
                              },
                              "text": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "filename": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Label the note is cited by, and the key notes are merged on when the hub is updated."
                              },
                              "isCompetitor": {
                                "type": "boolean"
                              },
                              "hasAttachment": {
                                "type": "boolean",
                                "description": "Whether the note carries a downloadable document."
                              }
                            }
                          }
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "knowledgeHub": {
                    "id": "68a1f8509c41d20014b3ee41",
                    "name": "Brightpay KB",
                    "companyName": "Brightpay",
                    "status": "complete",
                    "isDefault": true,
                    "websites": [
                      {
                        "url": "https://brightpay.com",
                        "includeSubPages": true,
                        "isCompetitor": false,
                        "parentUrl": null,
                        "lastCrawledAt": "2026-08-09T04:01:13.461Z"
                      },
                      {
                        "url": "https://brightpay.com/pricing",
                        "includeSubPages": false,
                        "isCompetitor": false,
                        "parentUrl": "https://brightpay.com",
                        "lastCrawledAt": null
                      }
                    ],
                    "notes": [
                      {
                        "id": "68a1f8509c41d20014b3ee55",
                        "text": "We sell payroll software to UK accountants.",
                        "filename": "positioning.md",
                        "isCompetitor": false,
                        "hasAttachment": true
                      }
                    ],
                    "createdAt": "2026-06-01T12:00:00.000Z",
                    "updatedAt": "2026-08-25T11:48:39.044Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The hub's full detail: its websites, its notes (with the ids the attachment endpoints address), its build status and whether it is the default hub. Readable by you and your teammates. `websites` lists the URLs you added together with the subpages the crawler discovered from them — a subpage carries the website it came from in `parentUrl`, and `lastCrawledAt` is null for a URL that has never been crawled successfully. `notes[].hasAttachment` tells you which notes have a document to download. Poll this endpoint while `status` is `processing`.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team (existence is never confirmed).\n- `422` `VALIDATION_FAILED` — hubId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      },
      "patch": {
        "operationId": "updateKnowledgeHub",
        "summary": "Update a hub's name, websites, or notes",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "knowledgeHub"
                  ],
                  "properties": {
                    "knowledgeHub": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "companyName",
                        "status",
                        "isDefault",
                        "websites",
                        "notes",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The new name if one was sent, otherwise the hub's current name."
                        },
                        "companyName": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Company name from the last completed build; null until a build has finished."
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "processing",
                            "complete",
                            "draft",
                            null
                          ],
                          "description": "processing = the crawl and page synthesis are running, complete = the hub is usable, draft = the hub is not built — either it was saved as a draft in the web app and never built, or its last build exhausted its retries."
                        },
                        "isDefault": {
                          "type": "boolean"
                        },
                        "websites": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "url",
                              "includeSubPages",
                              "isCompetitor",
                              "parentUrl",
                              "lastCrawledAt"
                            ],
                            "properties": {
                              "url": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "includeSubPages": {
                                "type": "boolean",
                                "description": "Whether the site's subpages were expanded when it was added."
                              },
                              "isCompetitor": {
                                "type": "boolean"
                              },
                              "parentUrl": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Set on subpages the crawler discovered: the website they were collected from. null on a website you added yourself."
                              },
                              "lastCrawledAt": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time",
                                "description": "When this URL was last successfully crawled; null if it has never been crawled."
                              }
                            }
                          },
                          "description": "The websites you added plus the subpages the crawler discovered from them (subpages carry parentUrl)."
                        },
                        "notes": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "text",
                              "filename",
                              "isCompetitor",
                              "hasAttachment"
                            ],
                            "properties": {
                              "id": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Note id; the attachment endpoints address notes by it."
                              },
                              "text": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "filename": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Label the note is cited by, and the key notes are merged on when the hub is updated."
                              },
                              "isCompetitor": {
                                "type": "boolean"
                              },
                              "hasAttachment": {
                                "type": "boolean",
                                "description": "Whether the note carries a downloadable document."
                              }
                            }
                          }
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "knowledgeHub": {
                    "id": "68a1f8509c41d20014b3ee41",
                    "name": "Brightpay KB",
                    "companyName": "Brightpay",
                    "status": "processing",
                    "isDefault": true,
                    "websites": [
                      {
                        "url": "https://brightpay.com",
                        "includeSubPages": true,
                        "isCompetitor": false,
                        "parentUrl": null,
                        "lastCrawledAt": "2026-08-09T04:01:13.461Z"
                      }
                    ],
                    "notes": [
                      {
                        "id": "68a1f8509c41d20014b3ee55",
                        "text": "We sell payroll software to UK accountants.",
                        "filename": "positioning.md",
                        "isCompetitor": false,
                        "hasAttachment": true
                      }
                    ],
                    "createdAt": "2026-06-01T12:00:00.000Z",
                    "updatedAt": "2026-08-25T12:04:11.221Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Renames the hub and/or merges websites and notes into it, then rebuilds it in the background (202). Websites merge by URL — a URL the hub already has is re-crawled, a new one is added — and notes merge by `filename`, so sending a known filename edits that note in place and keeps its attachment. Nothing is ever removed: there is no public way to drop a website or a note. The hub flips to `status` `processing` immediately; the `websites` and `notes` in this response are still the PRE-merge values, so poll `GET /business/knowledge-hubs/{hubId}` until `status` is `complete` to see the merged hub. A hub that is already processing a build, update or refresh answers 409 `KNOWLEDGE_HUB_NOT_READY`.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is already processing a build, update or refresh — wait for status complete.\n- `422` `VALIDATION_FAILED` — Nothing to update, a value outside its limits, or a website URL the crawler cannot parse.\n- `500` `UNEXPECTED_ERROR` — The update workflow could not be enqueued; the hub may be left processing — retry.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "New hub name (1-100 characters)."
                  },
                  "websites": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "minLength": 4,
                          "maxLength": 2048,
                          "description": "Website to crawl (4-2048 characters), with or without the scheme, e.g. brightpay.com or https://brightpay.com/pricing; an unparseable URL answers 422 VALIDATION_FAILED."
                        },
                        "includeSubPages": {
                          "type": "boolean",
                          "default": false,
                          "description": "Also crawl the site's subpages (up to 100 per crawl; a re-crawl skips subpages the hub already stores and keeps only the newly found ones); default false."
                        },
                        "isCompetitor": {
                          "type": "boolean",
                          "default": false,
                          "description": "Treat the site as a competitor: its content feeds competitor pages instead of the company's own profile; default false."
                        }
                      },
                      "required": [
                        "url"
                      ],
                      "description": "One website the hub is built from."
                    },
                    "minItems": 1,
                    "maxItems": 20,
                    "description": "Websites to add or re-crawl: at least 1, at most 20 per call, and the 20 caps the call, not the hub. Accepted values for each entry's url: any http(s) web address, with or without the scheme. Merged into the hub's existing websites — on a hub built through this API a known URL is matched ignoring scheme, www., a trailing slash and case — and a match is re-crawled while an unknown URL is added; nothing is ever removed. A matched entry is REPLACED by what you send, so omitting includeSubPages or isCompetitor resets that flag to false. Re-crawling runs in the background after the 202, so a site that cannot be fetched is not reported as an error: its entry simply keeps the lastCrawledAt it already had."
                  },
                  "notes": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "text": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 60000,
                          "description": "Free-text knowledge to include (1-60,000 characters), e.g. positioning, objection handling, internal docs."
                        },
                        "isCompetitor": {
                          "type": "boolean",
                          "default": false,
                          "description": "Treat the note as competitor material rather than the company's own; default false."
                        },
                        "filename": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 255,
                          "description": "Label the note is cited by, and the key it is merged on (1-255 characters). Required here because notes are merged by filename: a matching note is updated in place (its attachment is kept), an unknown filename adds a note. Free text, but to update an existing note it must equal one of the values from GET /business/knowledge-hubs/{hubId} (notes[].filename) exactly — the match is case-sensitive and literal, so a near-miss silently adds a second note instead of updating the one you meant. It is a label only: no file extension is needed, and it is unrelated to an attachment's own filename."
                        }
                      },
                      "required": [
                        "text",
                        "filename"
                      ],
                      "description": "One free-text note; attach a document to it afterwards via POST /business/knowledge-hubs/{hubId}/attachments."
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "Notes to add or update: at least 1, at most 50 per call. Each note's text carries the free-text knowledge itself; filename is only its label. Merged into the hub's existing notes by exact filename: a match keeps its id and its attachment but has its text and isCompetitor overwritten by exactly what you send, so omitting isCompetitor resets that flag to false and a competitor note silently becomes company material; an unknown filename adds a note, and nothing is removed. Two entries with the same filename in one call collapse into one — the last wins, with no error."
                  }
                },
                "description": "At least one of name, websites or notes is required."
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteKnowledgeHub",
        "summary": "Delete a hub",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Deletes a knowledge hub. The removal is soft: the hub stops appearing in any endpoint and stops grounding campaigns, and its knowledge store is retained. The default hub refuses deletion (409 `KNOWLEDGE_HUB_DEFAULT_UNDELETABLE`) — make another hub the default first. A hub whose first build has not produced a knowledge store yet — one still `processing`, or a `draft` whose build failed — cannot be deleted and answers 409 `KNOWLEDGE_HUB_NOT_READY`. Deleting a hub that is already deleted answers 404.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was already deleted, or it belongs to another team.\n- `409` `KNOWLEDGE_HUB_DEFAULT_UNDELETABLE` — The hub is the default one; make another hub the default first.\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is still building or its build failed before a knowledge store existed, so it cannot be deleted.\n- `422` `VALIDATION_FAILED` — hubId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/knowledge-hubs/{hubId}/refresh": {
      "post": {
        "operationId": "refreshKnowledgeHubWebsite",
        "summary": "Re-crawl one of the hub's websites",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "knowledgeHub"
                  ],
                  "properties": {
                    "knowledgeHub": {
                      "type": "object",
                      "required": [
                        "id",
                        "status"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "processing"
                          ],
                          "description": "The hub is processing the refresh; poll the hub detail until it is complete."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "knowledgeHub": {
                    "id": "68a1f8509c41d20014b3ee41",
                    "status": "processing"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Re-crawls one of the hub's websites and regenerates the knowledge pages built from it (202). Pass a URL that is already one of the hub's websites — from `websites[].url` in the hub detail; the match ignores scheme and `www.`, and a URL the hub does not have answers 404 `KNOWLEDGE_HUB_WEBSITE_NOT_FOUND`. Only the URL you pass is re-crawled: subpages the crawler already discovered from it are NOT re-crawled, and the pages built from them keep their existing text. When the website was added with `includeSubPages`, a refresh still picks up subpages that are new since the last crawl. To refresh a subpage, pass that subpage's own URL — every discovered subpage is itself one of the hub's `websites`. The hub flips to `status` `processing` at once; poll `GET /business/knowledge-hubs/{hubId}` until it is `complete`. Only the hub's owner can refresh, at most 3 times per minute and 25 per day on top of the shared rate bucket. Hubs built before knowledge pages cannot be refreshed (409 `KNOWLEDGE_HUB_PAGES_UNAVAILABLE`).\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `404` `KNOWLEDGE_HUB_WEBSITE_NOT_FOUND` — `url` is not one of the hub's websites.\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is still building, or is already processing another change.\n- `409` `KNOWLEDGE_HUB_PAGES_UNAVAILABLE` — The hub predates knowledge pages and cannot be refreshed.\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — You can read this teammate's hub but only its owner can refresh it.\n- `422` `VALIDATION_FAILED` — url missing or outside 4-2048 characters.\n- `500` `UNEXPECTED_ERROR` — The refresh workflow could not be enqueued; the hub is left complete — retry.\n- `429` `RATE_LIMITED` — The shared campaigns bucket was exceeded, or more than 3 refreshes in a minute / 25 in a day.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 2048,
                    "description": "One of the hub's website URLs, as listed in the hub detail (matched ignoring scheme and www); a URL that is not part of the hub answers 404."
                  }
                },
                "required": [
                  "url"
                ]
              }
            }
          }
        }
      }
    },
    "/business/knowledge-hubs/{hubId}/pages": {
      "get": {
        "operationId": "listKnowledgeHubPages",
        "summary": "The hub's knowledge pages",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "pages"
                  ],
                  "properties": {
                    "pages": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "title",
                          "content",
                          "category",
                          "origin",
                          "createdAt",
                          "updatedAt"
                        ],
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "title": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "content": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The page body in Markdown."
                          },
                          "category": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "overview",
                              "products",
                              "pricing",
                              "icp-use-cases",
                              "differentiators",
                              "competitors",
                              "faq",
                              "source-digest",
                              "custom",
                              null
                            ]
                          },
                          "origin": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "generated",
                              "edited",
                              "user",
                              null
                            ],
                            "description": "generated = synthesized from the hub's sources, edited = a generated page you have since edited, user = a page you authored."
                          },
                          "createdAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "pages": [
                    {
                      "id": "68a1fc209c41d20014b3f301",
                      "title": "Pricing",
                      "content": "## Plans\\n\\nStarter is 49 GBP per month per employer.",
                      "category": "pricing",
                      "origin": "generated",
                      "createdAt": "2026-06-01T12:04:55.387Z",
                      "updatedAt": "2026-08-09T04:12:03.126Z"
                    },
                    {
                      "id": "68a1fc209c41d20014b3f302",
                      "title": "Objections",
                      "content": "Price too high -> value framing.",
                      "category": "custom",
                      "origin": "user",
                      "createdAt": "2026-08-24T19:14:55.387Z",
                      "updatedAt": "2026-08-24T19:14:55.387Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The curated knowledge pages the hub was synthesized into — the documents campaign generation actually reads. Every page carries its full Markdown `content`, so a large hub answers a large body; there is no pagination. Sorted by category then title. `origin` is `generated` for a page the build wrote, `edited` for a generated page you have since edited, and `user` for a page you authored: generated and edited pages are rewritten when their sources are re-crawled, pages you authored never are. Readable by you and your teammates. Hubs built before knowledge pages have none and answer 409 `KNOWLEDGE_HUB_PAGES_UNAVAILABLE`.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `409` `KNOWLEDGE_HUB_PAGES_UNAVAILABLE` — The hub predates knowledge pages and has none.\n- `422` `VALIDATION_FAILED` — hubId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      },
      "post": {
        "operationId": "createKnowledgeHubPage",
        "summary": "Add a custom knowledge page",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "page"
                  ],
                  "properties": {
                    "page": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "content",
                        "category",
                        "origin",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The page body in Markdown."
                        },
                        "category": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "overview",
                            "products",
                            "pricing",
                            "icp-use-cases",
                            "differentiators",
                            "competitors",
                            "faq",
                            "source-digest",
                            "custom",
                            null
                          ]
                        },
                        "origin": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "generated",
                            "edited",
                            "user",
                            null
                          ],
                          "description": "generated = synthesized from the hub's sources, edited = a generated page you have since edited, user = a page you authored."
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "page": {
                    "id": "68a1fc209c41d20014b3f302",
                    "title": "Objection handling",
                    "content": "Price too high -> value framing.",
                    "category": "custom",
                    "origin": "user",
                    "createdAt": "2026-08-24T19:14:55.387Z",
                    "updatedAt": "2026-08-24T19:14:55.387Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Adds a page you author yourself to the hub and indexes it into the hub's knowledge store before answering — no polling. The page is stored with `origin` `user`, which means the hub's rebuilds never overwrite or remove it. `category` groups the page alongside the generated ones and defaults to `custom`. Only the hub's owner can add pages, and the hub needs a finished first build: a hub whose knowledge store does not exist yet — one still `processing`, or a `draft` — answers 409 `KNOWLEDGE_HUB_NOT_READY`, and a hub with no knowledge pages at all (one built before the pages pipeline, and a draft that was never built) answers 409 `KNOWLEDGE_HUB_PAGES_UNAVAILABLE` first.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is still building, or its build never finished.\n- `409` `KNOWLEDGE_HUB_PAGES_UNAVAILABLE` — The hub predates knowledge pages.\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — You can read this teammate's hub but only its owner can add pages.\n- `422` `VALIDATION_FAILED` — title or content missing or too long, or an unknown category.\n- `500` `UNEXPECTED_ERROR` — The page was saved but could not be indexed; edit it (PATCH) to retry the indexing.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Page title (1-200 characters)."
                  },
                  "content": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60000,
                    "description": "Page body in Markdown (1-60,000 characters); indexed into the hub's knowledge store as soon as the page is created."
                  },
                  "category": {
                    "type": "string",
                    "enum": [
                      "overview",
                      "products",
                      "pricing",
                      "icp-use-cases",
                      "differentiators",
                      "competitors",
                      "faq",
                      "source-digest",
                      "custom"
                    ],
                    "description": "Page category, one of overview (company summary), products, pricing, icp-use-cases (ideal customers and use cases), differentiators, competitors, faq, source-digest (digest of one source), custom (user-authored); defaults to custom."
                  }
                },
                "required": [
                  "title",
                  "content"
                ]
              }
            }
          }
        }
      }
    },
    "/business/knowledge-hubs/{hubId}/pages/{pageId}": {
      "patch": {
        "operationId": "updateKnowledgeHubPage",
        "summary": "Edit a page's title or content",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          },
          {
            "name": "pageId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge page (from GET /business/knowledge-hubs/{hubId}/pages).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge page (from GET /business/knowledge-hubs/{hubId}/pages)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "page"
                  ],
                  "properties": {
                    "page": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "content",
                        "origin",
                        "updatedAt"
                      ],
                      "description": "The fields the update reports. Read the page back with GET /business/knowledge-hubs/{hubId}/pages for its category and createdAt.",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The page body in Markdown, as stored after this call."
                        },
                        "origin": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "generated",
                            "edited",
                            "user",
                            null
                          ],
                          "description": "`edited` after you edit a generated page, `user` for a page you authored yourself."
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "page": {
                    "id": "68a1fc209c41d20014b3f301",
                    "title": "Pricing and plans",
                    "content": "## Plans\\n\\nStarter is 49 GBP per month per employer.",
                    "origin": "edited",
                    "updatedAt": "2026-08-25T16:49:57.052Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Edits a page's title and/or Markdown content and re-indexes it into the hub's knowledge store before answering. Editing a generated page flips its `origin` to `edited`; it keeps your text until its sources are re-crawled, at which point an update or refresh of the hub regenerates it. Pages you authored (`origin` `user`) keep your edits permanently. The response carries only the fields this call changes; list the hub's pages for a page's category and createdAt. Only the hub's owner can edit pages.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `404` `KNOWLEDGE_PAGE_NOT_FOUND` — No page with that id on this hub.\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is still building, or its build never finished.\n- `409` `KNOWLEDGE_HUB_PAGES_UNAVAILABLE` — The hub predates knowledge pages.\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — You can read this teammate's hub but only its owner can edit pages.\n- `422` `VALIDATION_FAILED` — Neither title nor content given, or a value too long.\n- `500` `UNEXPECTED_ERROR` — The edit was saved but could not be re-indexed; retry the PATCH.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "New page title (1-200 characters)."
                  },
                  "content": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 60000,
                    "description": "New Markdown body (1-60,000 characters); a generated page becomes an edited one but is still refreshed when its sources change."
                  }
                },
                "description": "At least one of title or content is required."
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteKnowledgeHubPage",
        "summary": "Remove a knowledge page",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          },
          {
            "name": "pageId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge page (from GET /business/knowledge-hubs/{hubId}/pages).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge page (from GET /business/knowledge-hubs/{hubId}/pages)."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Removes a page from the hub and from its knowledge store immediately, so campaign generation stops using it. A generated page may reappear when the hub is next updated or refreshed if its sources still exist; a page you authored is gone for good. Only the hub's owner can delete pages.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `404` `KNOWLEDGE_PAGE_NOT_FOUND` — No page with that id on this hub.\n- `409` `KNOWLEDGE_HUB_PAGES_UNAVAILABLE` — The hub predates knowledge pages.\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — You can read this teammate's hub but only its owner can delete pages.\n- `422` `VALIDATION_FAILED` — hubId or pageId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/knowledge-hubs/{hubId}/pages/{pageId}/regenerate": {
      "post": {
        "operationId": "regenerateKnowledgeHubPage",
        "summary": "Rebuild a page from the hub's sources",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          },
          {
            "name": "pageId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge page (from GET /business/knowledge-hubs/{hubId}/pages).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge page (from GET /business/knowledge-hubs/{hubId}/pages)."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "page"
                  ],
                  "properties": {
                    "page": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "content",
                        "origin",
                        "updatedAt"
                      ],
                      "description": "The fields the update reports. Read the page back with GET /business/knowledge-hubs/{hubId}/pages for its category and createdAt.",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "content": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The page body in Markdown, as stored after this call."
                        },
                        "origin": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "generated",
                            "edited",
                            "user",
                            null
                          ],
                          "description": "Always `generated` after a regeneration — the rebuild discards the `edited` marker."
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "page": {
                    "id": "68a1fc209c41d20014b3f301",
                    "title": "Pricing",
                    "content": "## Plans\\n\\nStarter is 49 GBP per month per employer.",
                    "origin": "generated",
                    "updatedAt": "2026-08-25T16:52:11.004Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Rebuilds a generated page from the hub's cached sources — the crawled website text and the notes it was written from — discarding any manual edits, and re-indexes it. The work finishes before the response: the `content` you get back is already the regenerated page and its `origin` is reset to `generated`, so there is nothing to poll. Pages you authored have no sources and answer 409 `KNOWLEDGE_PAGE_NOT_REGENERABLE`; so does a generated page whose sources have since been removed. Only the hub's owner can regenerate, at most 10 times per minute and 200 per day on top of the shared rate bucket.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `404` `KNOWLEDGE_PAGE_NOT_FOUND` — No page with that id on this hub.\n- `409` `KNOWLEDGE_PAGE_NOT_REGENERABLE` — The page has no cached sources to rebuild from (you authored it, or its sources were removed).\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is still building, or its build never finished.\n- `409` `KNOWLEDGE_HUB_PAGES_UNAVAILABLE` — The hub predates knowledge pages.\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — You can read this teammate's hub but only its owner can regenerate pages.\n- `422` `VALIDATION_FAILED` — hubId or pageId is not a 24-character hex id.\n- `500` `UNEXPECTED_ERROR` — The synthesis model failed, or the regenerated page could not be re-indexed — retry.\n- `429` `RATE_LIMITED` — The shared campaigns bucket was exceeded, or more than 10 regenerations in a minute / 200 in a day.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/knowledge-hubs/{hubId}/attachments": {
      "post": {
        "operationId": "uploadKnowledgeHubAttachment",
        "summary": "Attach a document to one of the hub's notes",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "attachment"
                  ],
                  "properties": {
                    "attachment": {
                      "type": "object",
                      "required": [
                        "noteId",
                        "filename",
                        "contentType",
                        "byteSize"
                      ],
                      "properties": {
                        "noteId": {
                          "type": "string",
                          "description": "The note the document is attached to."
                        },
                        "filename": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The file name as stored."
                        },
                        "contentType": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "application/pdf",
                            "text/plain",
                            "text/csv",
                            "application/msword",
                            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                            "application/rtf",
                            null
                          ]
                        },
                        "byteSize": {
                          "type": [
                            "integer",
                            "null"
                          ],
                          "description": "Size of the stored file in bytes."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "attachment": {
                    "noteId": "68a1f8509c41d20014b3ee55",
                    "filename": "positioning.pdf",
                    "contentType": "application/pdf",
                    "byteSize": 284913
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Attaches a document to one of the hub's notes; note ids come from `notes[].id` in the hub detail. Send the file as padded base64 in `fileBase64`, up to 10,485,760 characters (about 7.5 MB of file data); allowed types are PDF, plain text, CSV, Word (.doc and .docx) and RTF. The file is stored for download only — it is not parsed into the hub's knowledge, so put the text you want the hub to learn in the note's own `text`. A note holds one attachment: a second upload answers 409 `ATTACHMENT_ALREADY_EXISTS`, and there is no replace endpoint. The response does not include a download URL; fetch one with `GET /business/knowledge-hubs/{hubId}/attachments/{noteId}`. Only the hub's owner can upload, and not while the hub is `processing`.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `404` `NOTE_NOT_FOUND` — No note with that id on this hub.\n- `409` `ATTACHMENT_ALREADY_EXISTS` — The note already holds a document; delete the note's attachment first.\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is processing a build, update or refresh.\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — You can read this teammate's hub but only its owner can upload attachments.\n- `422` `VALIDATION_FAILED` — Malformed base64, a file over the size cap, an unsupported contentType, or a missing field.\n- `500` `UNEXPECTED_ERROR` — The file could not be stored; retry.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "noteId": {
                    "type": "string",
                    "description": "24-character hex id of the note to attach the document to; a note holds at most one attachment."
                  },
                  "fileBase64": {
                    "type": "string",
                    "maxLength": 10485760,
                    "description": "Accepted values: standard base64 with padding — alphabet A-Z a-z 0-9 + / and a length that is a multiple of 4. A URL-safe (-_) string, an unpadded one, or one that still carries a data:...;base64, prefix answers 422 VALIDATION_FAILED. The whole JSON request body is capped at 10 MB, which puts the real ceiling at roughly 7.5 MB of file data (base64 is a third larger than the file it encodes). The bytes are stored and handed back by the download endpoint unchanged: nothing reads, extracts or indexes them, so an attachment on its own adds no knowledge to the hub — only the note's text does."
                  },
                  "filename": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "File name stored with the attachment and returned by the download endpoint (1-255 characters). Free text: it is stored verbatim, never parsed, and never checked against contentType or against the note's own filename label — an extension that contradicts contentType is accepted and changes nothing. Give it the real extension anyway, since it is the name whoever opens the download sees."
                  },
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "application/pdf",
                      "text/plain",
                      "text/csv",
                      "application/msword",
                      "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                      "application/rtf"
                    ],
                    "description": "MIME type of the file: PDF, plain text, CSV, Word (.doc or .docx) or RTF."
                  }
                },
                "required": [
                  "noteId",
                  "fileBase64",
                  "filename",
                  "contentType"
                ]
              }
            }
          }
        }
      }
    },
    "/business/knowledge-hubs/{hubId}/attachments/{noteId}": {
      "get": {
        "operationId": "getKnowledgeHubAttachment",
        "summary": "A download URL for a note's attachment",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          },
          {
            "name": "noteId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the note (notes[].id in GET /business/knowledge-hubs/{hubId}).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the note (notes[].id in GET /business/knowledge-hubs/{hubId})."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "attachment"
                  ],
                  "properties": {
                    "attachment": {
                      "type": "object",
                      "required": [
                        "noteId",
                        "filename",
                        "contentType",
                        "byteSize",
                        "downloadUrl"
                      ],
                      "properties": {
                        "noteId": {
                          "type": "string"
                        },
                        "filename": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "contentType": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "application/pdf",
                            "text/plain",
                            "text/csv",
                            "application/msword",
                            "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
                            "application/rtf",
                            null
                          ]
                        },
                        "byteSize": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "downloadUrl": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "uri",
                          "description": "Presigned URL, valid for one hour."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "attachment": {
                    "noteId": "68a1f8509c41d20014b3ee55",
                    "filename": "positioning.pdf",
                    "contentType": "application/pdf",
                    "byteSize": 284913,
                    "downloadUrl": "https://kompassai-uploaded-files.s3.us-east-1.amazonaws.com/knowledge-hub-attachments/68a1f8509c41d20014b3ee55-positioning.pdf?X-Amz-Expires=3600&X-Amz-Signature=1f0b4c2d"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Returns a presigned download URL for the document attached to a note, together with the stored file name, MIME type and size. The URL is valid for one hour; request a fresh one when it expires. Readable by you and your teammates. A note that has no document answers 404 `ATTACHMENT_NOT_FOUND`, and a note id the hub does not have answers 404 `NOTE_NOT_FOUND`.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `404` `NOTE_NOT_FOUND` — No note with that id on this hub.\n- `404` `ATTACHMENT_NOT_FOUND` — The note has no document attached.\n- `422` `VALIDATION_FAILED` — hubId or noteId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      },
      "delete": {
        "operationId": "deleteKnowledgeHubAttachment",
        "summary": "Remove a note's attachment",
        "tags": [
          "Knowledge hubs"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "hubId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the knowledge hub (from GET /business/knowledge-hubs)."
            }
          },
          {
            "name": "noteId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the note (notes[].id in GET /business/knowledge-hubs/{hubId}).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the note (notes[].id in GET /business/knowledge-hubs/{hubId})."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Deletes the document attached to a note. Be aware that this removes the WHOLE note from the hub — the note's `text` as well as the file — so if you only meant to drop the document, re-add the note afterwards with `PATCH /business/knowledge-hubs/{hubId}` (same `filename`, same `text`). A note that has no document is left untouched and answers 404 `ATTACHMENT_NOT_FOUND`. Only the hub's owner can delete, and not while the hub is `processing`.\n\nErrors:\n- `404` `KNOWLEDGE_HUB_NOT_FOUND` — No hub with that id, it was deleted, or it belongs to another team.\n- `404` `NOTE_NOT_FOUND` — No note with that id on this hub.\n- `404` `ATTACHMENT_NOT_FOUND` — The note has no document attached, so there is nothing to delete.\n- `409` `KNOWLEDGE_HUB_NOT_READY` — The hub is processing a build, update or refresh.\n- `403` `KNOWLEDGE_HUB_OWNER_ONLY` — You can read this teammate's hub but only its owner can delete attachments.\n- `422` `VALIDATION_FAILED` — hubId or noteId is not a 24-character hex id.\n- `500` `UNEXPECTED_ERROR` — The stored file could not be removed; the note is kept — retry.\n- `429` `RATE_LIMITED` — More than 30 knowledge-hub/campaign requests in a minute (or 1000 in a day). Knowledge hubs share the campaigns bucket.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/imports/presign": {
      "post": {
        "operationId": "createImportPresign",
        "summary": "Presigned upload for a large import file",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "upload"
                  ],
                  "properties": {
                    "upload": {
                      "type": "object",
                      "required": [
                        "importId",
                        "uploadUrl",
                        "method",
                        "expiresIn"
                      ],
                      "properties": {
                        "importId": {
                          "type": "string"
                        },
                        "uploadUrl": {
                          "type": "string"
                        },
                        "method": {
                          "type": "string",
                          "enum": [
                            "PUT"
                          ]
                        },
                        "expiresIn": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "upload": {
                    "importId": "dXBsb2Fkcy82OGExZjIwYjljNDFkMjAwMTRiM2U5MDEvM2Y2ZjBlMmEtOGQ0Yi00ZTFhLTk3YzItNWQ4YjFmMGUyYTdjLmNzdg",
                    "uploadUrl": "https://fuseai-csv-uploads.s3.us-east-1.amazonaws.com/uploads/68a1f20b9c41d20014b3e901/3f6f0e2a-8d4b-4e1a-97c2-5d8b1f0e2a7c.csv?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=600&X-Amz-Signature=9c1e4b2a7d3f5e6c",
                    "method": "PUT",
                    "expiresIn": 600
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Issues a presigned S3 PUT for a CSV/XLS/XLSX import file larger than the 10MB multipart line (up to 50MB). PUT the raw file bytes to `uploadUrl` with the same `Content-Type` you declared, within `expiresIn` seconds (600), then pass the returned `importId` to `POST /business/imports` for the preview, or straight to `POST /business/imports/{importId}/commit`. Nothing is parsed or billed at this step.\n\nErrors:\n- `422` `IMPORT_FILE_UNSUPPORTED` — The presign service refused the content type (reachable only if its allow-list and the documented enum drift apart).\n- `422` `VALIDATION_FAILED` — filename missing/blank or contentType outside the three supported MIME types.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filename": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500,
                    "description": "Original file name, e.g. leads.csv (1-500 characters). Free text kept for your own reference: it does not name the stored object, and the file's format is read from contentType alone, so an extension that disagrees with contentType changes nothing."
                  },
                  "contentType": {
                    "type": "string",
                    "enum": [
                      "text/csv",
                      "application/vnd.ms-excel",
                      "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                    ],
                    "description": "MIME type of the file to upload: text/csv, application/vnd.ms-excel (XLS) or application/vnd.openxmlformats-officedocument.spreadsheetml.sheet (XLSX); the PUT to uploadUrl must send the same Content-Type."
                  }
                },
                "required": [
                  "filename",
                  "contentType"
                ]
              }
            }
          }
        }
      }
    },
    "/business/imports": {
      "post": {
        "operationId": "createImport",
        "summary": "Start an import (parse + suggested mapping)",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "import"
                  ],
                  "properties": {
                    "import": {
                      "type": "object",
                      "required": [
                        "importId",
                        "filename",
                        "rowCount",
                        "headers",
                        "sampleRows",
                        "suggestedMapping"
                      ],
                      "properties": {
                        "importId": {
                          "type": "string"
                        },
                        "filename": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "rowCount": {
                          "type": "integer"
                        },
                        "headers": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "sampleRows": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        },
                        "suggestedMapping": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "import": {
                    "importId": "dXBsb2Fkcy82OGExZjIwYjljNDFkMjAwMTRiM2U5MDEvM2Y2ZjBlMmEtOGQ0Yi00ZTFhLTk3YzItNWQ4YjFmMGUyYTdjLmNzdg",
                    "filename": "leads.csv",
                    "rowCount": 1240,
                    "headers": [
                      "First Name",
                      "Last Name",
                      "Email",
                      "Company",
                      "Tel",
                      "Deal stage"
                    ],
                    "sampleRows": [
                      {
                        "First Name": "Sam",
                        "Last Name": "Rivera",
                        "Email": "sam@brightpay.com",
                        "Company": "Brightpay",
                        "Tel": "+13015023231",
                        "Deal stage": "Discovery"
                      },
                      {
                        "First Name": "Ada",
                        "Last Name": "Nwosu",
                        "Email": "ada@brightpay.com",
                        "Company": "Brightpay",
                        "Tel": "+13015023232",
                        "Deal stage": "Proposal"
                      }
                    ],
                    "suggestedMapping": {
                      "First Name": "First Name",
                      "Last Name": "Last Name",
                      "Email": "Email",
                      "Company": "Company",
                      "Tel": "Phone",
                      "Deal stage": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Starts an import from a spreadsheet. Two intake shapes: a multipart request carrying the file (CSV/XLS/XLSX, ≤10MB — larger files go through `POST /business/imports/presign` first) or a JSON body naming a presigned upload's `importId`. The call only parses: it answers 200 with the mapping-confirmation payload — `rowCount`, the detected `headers`, up to five `sampleRows`, and `suggestedMapping` (source header → standard field label such as `First Name`, `Email`, `Company`; null when nothing was suggested) — and stores that suggestion on the import. Nothing is written to any list until `POST /business/imports/{importId}/commit`, which is the only call that takes a destination. Parsing spends no credits.\n\nErrors:\n- `400` `IMPORT_FILE_MISSING` — Neither a multipart file part nor an importId was sent.\n- `404` `IMPORT_NOT_FOUND` — importId does not decode to an upload of the token owner, or the uploaded object is gone.\n- `409` `IMPORT_ALREADY_COMMITTED` — The import was already committed; a committed file is never re-parsed. Upload it again for a new import.\n- `422` `IMPORT_FILE_UNSUPPORTED` — The multipart part carries no Content-Type or one that is not CSV/XLS/XLSX, or the file could not be parsed.\n- `422` `IMPORT_FILE_TOO_LARGE` — Multipart file over 10MB, or a presigned object over 50MB.\n- `422` `IMPORT_FILE_EMPTY` — The file has no data rows.\n- `422` `VALIDATION_FAILED` — A body key other than importId (destination fields belong to the commit call).\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "importId": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 800,
                    "description": "The importId returned by POST /business/imports/presign, once the file has been PUT to its uploadUrl; omit when the file is sent as a multipart part of this request."
                  }
                }
              }
            },
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "The spreadsheet to import (.csv or .xlsx). Any part name is accepted; the first non-empty file part is used. The part must carry its Content-Type (text/csv, application/vnd.ms-excel or the XLSX type)."
                  }
                },
                "required": [
                  "file"
                ]
              }
            }
          }
        }
      }
    },
    "/business/imports/{importId}/commit": {
      "post": {
        "operationId": "commitImport",
        "summary": "Commit an import into a list",
        "tags": [
          "Lists"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "importId",
            "in": "path",
            "required": true,
            "description": "The importId returned by POST /business/imports (or /business/imports/presign) that identifies the uploaded file.",
            "schema": {
              "type": "string",
              "minLength": 8,
              "maxLength": 800,
              "description": "The importId returned by POST /business/imports (or /business/imports/presign) that identifies the uploaded file."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "import"
                  ],
                  "properties": {
                    "import": {
                      "type": "object",
                      "required": [
                        "importId",
                        "listId",
                        "jobId",
                        "mapping",
                        "ignoredHeaders"
                      ],
                      "properties": {
                        "importId": {
                          "type": "string"
                        },
                        "listId": {
                          "type": "string"
                        },
                        "jobId": {
                          "type": "string"
                        },
                        "mapping": {
                          "type": "object",
                          "description": "Source header → template label the import ran with; null for a header that was left out.",
                          "additionalProperties": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "ignoredHeaders": {
                          "type": "array",
                          "description": "Headers no template label claimed; their values did not reach the list.",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "import": {
                    "importId": "dXBsb2Fkcy82OGExZjIwYjljNDFkMjAwMTRiM2U5MDEvM2Y2ZjBlMmEtOGQ0Yi00ZTFhLTk3YzItNWQ4YjFmMGUyYTdjLmNzdg",
                    "listId": "68a1f20b9c41d20014b3e901",
                    "jobId": "3f6f0e2a-8d4b-4e1a-97c2-5d8b1f0e2a7c",
                    "mapping": {
                      "First Name": "First Name",
                      "Last Name": "Last Name",
                      "Email": "Email",
                      "Company": "Company",
                      "Tel": "Phone",
                      "Deal stage": null
                    },
                    "ignoredHeaders": [
                      "Deal stage"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Runs a parsed import into a list, exactly once: append to an existing list with `listId`, or name the destination with `listName` (an existing list with that exact, case-insensitive name is reused, otherwise it is created). The column mapping is resolved for every header before anything runs — your `mapping` entry first, then the suggestion stored by `POST /business/imports`, then the standard header names — and the 202 echoes the `mapping` the import ran with plus the `ignoredHeaders` it dropped. A file in which no column resolves to an identity field (LinkedIn URL, Email, or a name plus Company Domain) is refused with 422 IMPORT_IDENTITY_MISSING rather than imported as unmatched rows. `onDuplicate` decides what a row matching an existing member does: `merge` (default) fills the member's empty fields and keeps it, `skip` drops the row, `replace` saves the row as a new contact and removes the member. `enrich` runs enrichment on the imported rows in the same job (`none` = raw rows, `email`/`phone`/`phone_and_email` = the waterfall, `demographics` = resolve to canonical contacts; billed like `POST /business/lists/{listId}/enrich`). A second commit of the same importId answers 409. Async: 202. `jobId` is an opaque orchestration reference and is NOT pollable — poll `GET /business/lists/{listId}` until `completionStatus` leaves `processing`.\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — `enrich` is `email`, `phone` or `phone_and_email` and the credit balance does not cover saving and enriching every row of the file at the reserved (worst-case) price: rows the import later drops (duplicates within the file, rows with no usable identity) are priced too. Nothing was imported or billed.\n- `404` `IMPORT_NOT_FOUND` — importId does not decode to an upload of the token owner, or a presigned upload was never PUT.\n- `409` `IMPORT_ALREADY_COMMITTED` — This import already ran; a commit is single-shot. Upload the file again to import it again.\n- `422` `IMPORT_IDENTITY_MISSING` — After the explicit mapping, the stored suggestion and the standard header names, no column resolves to LinkedIn URL, Email, or a name plus Company Domain — rows could not be matched against the list, so nothing was imported. `param` is `mapping`.\n- `422` `IMPORT_FILE_UNSUPPORTED` — A presigned upload committed without a preview call could not be parsed.\n- `422` `IMPORT_FILE_TOO_LARGE` — A presigned upload committed without a preview call is over 50MB.\n- `422` `IMPORT_FILE_EMPTY` — The file has no data rows.\n- `404` `LIST_NOT_FOUND` — The destination listId is unknown or not owned.\n- `409` `LIST_NAME_AMBIGUOUS` — More than one list carries listName — reference the destination by id.\n- `422` `LIST_NAME_RESERVED` — listName is a system/dynamic list title and cannot be a destination.\n- `422` `VALIDATION_FAILED` — Neither or both of listId/listName, an unknown body key, an invalid enrich or onDuplicate value, or a mapping value that is not one of the template labels.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "listId": {
                    "type": "string",
                    "description": "24-character hex id of an existing contact list to append the rows to; mutually exclusive with listName, and an unknown or non-owned id answers 404 LIST_NOT_FOUND."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Name of the destination contact list (1-255 characters): an existing list with this exact name (case-insensitive) is reused, otherwise it is created; mutually exclusive with listId. Two lists sharing the name answer 409 LIST_NAME_AMBIGUOUS and reserved system titles answer 422 LIST_NAME_RESERVED."
                  },
                  "mapping": {
                    "type": "object",
                    "properties": {},
                    "description": "Column mapping from source column header to target field, e.g. {\"fname\": \"First Name\"} (up to 200 entries). Each key is a column header spelled exactly as it appears in the file (the `headers` of the import preview). Each value is one of these template labels, spelled and cased exactly like this: Full Name, First Name, Last Name, LinkedIn URL, Company, Company Domain, Job Title, Job Level, Department, Industry, Country, State, City, Email, Phone (the synonyms linkedinUrl, linkedin, Company Name, Mobile Phone, Seniority, Level are accepted and read as the label they stand for). Any other value is rejected with VALIDATION_FAILED. A header with no target carries null and is left out, so the suggestedMapping from POST /business/imports can be sent back unchanged. Headers you leave out of the mapping fall back to the stored suggestion, then to the standard header names (email, first_name, title, domain, url, position ...); the 202 response echoes the mapping the import ran with and lists every header it ignored. When two headers name the same label only the first one is used."
                  },
                  "enrich": {
                    "type": "string",
                    "enum": [
                      "none",
                      "email",
                      "phone",
                      "phone_and_email",
                      "demographics"
                    ],
                    "description": "Enrichment to run on the imported rows: none (default, rows saved exactly as uploaded), email, phone or phone_and_email (the enrichment waterfall, billed per contact processed) or demographics (resolve rows to canonical contacts, 2 credits per resolved contact)."
                  },
                  "onDuplicate": {
                    "type": "string",
                    "enum": [
                      "merge",
                      "skip",
                      "replace"
                    ],
                    "description": "What to do with a row that matches a contact already in the destination list (matched by LinkedIn URL, then email, then name plus company domain). merge (default): fill the existing contact's empty fields from the row and keep it in the list. skip: leave the existing contact untouched and drop the row. replace: save the row as a new contact and remove the existing one from the list. With enrich set to anything but none, merge and replace both enrich the existing contact in place and skip leaves it out of the enrichment."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/business/analytics/campaigns": {
      "get": {
        "operationId": "getCampaignAnalytics",
        "summary": "Campaigns analytics roll-up",
        "tags": [
          "Analytics"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "default": "30d",
              "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "range": {
                      "type": "string",
                      "enum": [
                        "7d",
                        "30d",
                        "90d"
                      ]
                    },
                    "email": {
                      "type": "object",
                      "properties": {
                        "trend": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "totals": {
                              "type": "object",
                              "properties": {
                                "sent": {
                                  "type": "integer"
                                },
                                "ai": {
                                  "type": "integer"
                                },
                                "manual": {
                                  "type": "integer"
                                },
                                "opened": {
                                  "type": "integer"
                                },
                                "uniqueOpened": {
                                  "type": "integer"
                                },
                                "clicked": {
                                  "type": "integer"
                                },
                                "uniqueClicked": {
                                  "type": "integer"
                                },
                                "replied": {
                                  "type": "integer"
                                },
                                "positiveReplies": {
                                  "type": "integer"
                                },
                                "bounced": {
                                  "type": "integer"
                                },
                                "invalidated": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "sent",
                                "ai",
                                "manual",
                                "opened",
                                "uniqueOpened",
                                "clicked",
                                "uniqueClicked",
                                "replied",
                                "positiveReplies",
                                "bounced",
                                "invalidated"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "isoDate": {
                                    "type": "string"
                                  },
                                  "sent": {
                                    "type": "integer"
                                  },
                                  "ai": {
                                    "type": "integer"
                                  },
                                  "manual": {
                                    "type": "integer"
                                  },
                                  "opened": {
                                    "type": "integer"
                                  },
                                  "uniqueOpened": {
                                    "type": "integer"
                                  },
                                  "clicked": {
                                    "type": "integer"
                                  },
                                  "uniqueClicked": {
                                    "type": "integer"
                                  },
                                  "replied": {
                                    "type": "integer"
                                  },
                                  "positiveReplies": {
                                    "type": "integer"
                                  },
                                  "bounced": {
                                    "type": "integer"
                                  },
                                  "invalidated": {
                                    "type": "integer"
                                  },
                                  "cohortOpened": {
                                    "type": "integer"
                                  },
                                  "cohortClicked": {
                                    "type": "integer"
                                  },
                                  "cohortBounced": {
                                    "type": "integer"
                                  },
                                  "cohortReplied": {
                                    "type": "integer"
                                  },
                                  "cohortPositiveReplies": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "isoDate",
                                  "sent",
                                  "ai",
                                  "manual",
                                  "opened",
                                  "uniqueOpened",
                                  "clicked",
                                  "uniqueClicked",
                                  "replied",
                                  "positiveReplies",
                                  "bounced",
                                  "invalidated",
                                  "cohortOpened",
                                  "cohortClicked",
                                  "cohortBounced",
                                  "cohortReplied",
                                  "cohortPositiveReplies"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totals",
                            "series"
                          ]
                        }
                      },
                      "required": [
                        "trend"
                      ]
                    },
                    "linkedin": {
                      "type": "object",
                      "properties": {
                        "trend": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "totals": {
                              "type": "object",
                              "properties": {
                                "sent": {
                                  "type": "integer"
                                },
                                "inmailsSent": {
                                  "type": "integer"
                                },
                                "profileVisits": {
                                  "type": "integer"
                                },
                                "postsLiked": {
                                  "type": "integer"
                                },
                                "ai": {
                                  "type": "integer"
                                },
                                "manual": {
                                  "type": "integer"
                                },
                                "invitesSent": {
                                  "type": "integer"
                                },
                                "invitesAccepted": {
                                  "type": "integer"
                                },
                                "replied": {
                                  "type": "integer"
                                },
                                "positiveReplies": {
                                  "type": "integer"
                                },
                                "bounced": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "sent",
                                "inmailsSent",
                                "profileVisits",
                                "postsLiked",
                                "ai",
                                "manual",
                                "invitesSent",
                                "invitesAccepted",
                                "replied",
                                "positiveReplies",
                                "bounced"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "isoDate": {
                                    "type": "string"
                                  },
                                  "sent": {
                                    "type": "integer"
                                  },
                                  "inmailsSent": {
                                    "type": "integer"
                                  },
                                  "profileVisits": {
                                    "type": "integer"
                                  },
                                  "postsLiked": {
                                    "type": "integer"
                                  },
                                  "ai": {
                                    "type": "integer"
                                  },
                                  "manual": {
                                    "type": "integer"
                                  },
                                  "invitesSent": {
                                    "type": "integer"
                                  },
                                  "invitesAccepted": {
                                    "type": "integer"
                                  },
                                  "replied": {
                                    "type": "integer"
                                  },
                                  "positiveReplies": {
                                    "type": "integer"
                                  },
                                  "bounced": {
                                    "type": "integer"
                                  },
                                  "cohortInvitesAccepted": {
                                    "type": "integer"
                                  },
                                  "cohortReplies": {
                                    "type": "integer"
                                  },
                                  "cohortPositiveReplies": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "isoDate",
                                  "sent",
                                  "inmailsSent",
                                  "profileVisits",
                                  "postsLiked",
                                  "ai",
                                  "manual",
                                  "invitesSent",
                                  "invitesAccepted",
                                  "replied",
                                  "positiveReplies",
                                  "bounced",
                                  "cohortInvitesAccepted",
                                  "cohortReplies",
                                  "cohortPositiveReplies"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totals",
                            "series"
                          ]
                        },
                        "topCampaigns": {
                          "type": [
                            "array",
                            "null"
                          ],
                          "items": {
                            "type": "object",
                            "properties": {
                              "campaignId": {
                                "type": "string"
                              },
                              "campaignName": {
                                "type": "string"
                              },
                              "connectionRequestsSent": {
                                "type": "integer"
                              },
                              "connectionsAccepted": {
                                "type": "integer"
                              },
                              "repliesReceived": {
                                "type": "integer"
                              },
                              "positiveRepliesReceived": {
                                "type": "integer"
                              },
                              "acceptanceRate": {
                                "type": "number"
                              },
                              "connectionReplyRate": {
                                "type": "number"
                              },
                              "positiveReplyRate": {
                                "type": "number"
                              }
                            },
                            "required": [
                              "campaignId",
                              "campaignName",
                              "connectionRequestsSent",
                              "connectionsAccepted",
                              "repliesReceived",
                              "positiveRepliesReceived",
                              "acceptanceRate",
                              "connectionReplyRate",
                              "positiveReplyRate"
                            ]
                          }
                        }
                      },
                      "required": [
                        "trend",
                        "topCampaigns"
                      ]
                    }
                  },
                  "required": [
                    "range",
                    "email",
                    "linkedin"
                  ]
                },
                "example": {
                  "range": "30d",
                  "email": {
                    "trend": {
                      "totals": {
                        "sent": 66,
                        "ai": 20,
                        "manual": 46,
                        "opened": 41,
                        "uniqueOpened": 28,
                        "clicked": 9,
                        "uniqueClicked": 7,
                        "replied": 6,
                        "positiveReplies": 2,
                        "bounced": 1,
                        "invalidated": 3
                      },
                      "series": [
                        {
                          "date": "Jul 27",
                          "isoDate": "2026-07-27",
                          "sent": 32,
                          "ai": 20,
                          "manual": 12,
                          "opened": 22,
                          "uniqueOpened": 15,
                          "clicked": 5,
                          "uniqueClicked": 4,
                          "replied": 4,
                          "positiveReplies": 1,
                          "bounced": 1,
                          "invalidated": 2,
                          "cohortOpened": 13,
                          "cohortClicked": 3,
                          "cohortBounced": 1,
                          "cohortReplied": 3,
                          "cohortPositiveReplies": 1
                        },
                        {
                          "date": "Aug 3",
                          "isoDate": "2026-08-03",
                          "sent": 34,
                          "ai": 0,
                          "manual": 34,
                          "opened": 19,
                          "uniqueOpened": 13,
                          "clicked": 4,
                          "uniqueClicked": 3,
                          "replied": 2,
                          "positiveReplies": 1,
                          "bounced": 0,
                          "invalidated": 1,
                          "cohortOpened": 11,
                          "cohortClicked": 3,
                          "cohortBounced": 0,
                          "cohortReplied": 2,
                          "cohortPositiveReplies": 1
                        }
                      ]
                    }
                  },
                  "linkedin": {
                    "trend": {
                      "totals": {
                        "sent": 183,
                        "inmailsSent": 6,
                        "profileVisits": 46,
                        "postsLiked": 14,
                        "ai": 33,
                        "manual": 154,
                        "invitesSent": 156,
                        "invitesAccepted": 52,
                        "replied": 29,
                        "positiveReplies": 4,
                        "bounced": 9
                      },
                      "series": [
                        {
                          "date": "Jul 27",
                          "isoDate": "2026-07-27",
                          "sent": 95,
                          "inmailsSent": 4,
                          "profileVisits": 30,
                          "postsLiked": 8,
                          "ai": 15,
                          "manual": 80,
                          "invitesSent": 130,
                          "invitesAccepted": 38,
                          "replied": 20,
                          "positiveReplies": 3,
                          "bounced": 5,
                          "cohortInvitesAccepted": 40,
                          "cohortReplies": 11,
                          "cohortPositiveReplies": 4
                        }
                      ]
                    },
                    "topCampaigns": [
                      {
                        "campaignId": "69c50c3da19bd0c24ab4b503",
                        "campaignName": "Qa linkedin campaign",
                        "connectionRequestsSent": 132,
                        "connectionsAccepted": 130,
                        "repliesReceived": 29,
                        "positiveRepliesReceived": 0,
                        "acceptanceRate": 98.48,
                        "connectionReplyRate": 22.31,
                        "positiveReplyRate": 0
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The campaigns insights tab in one response for the whole account (every campaign the token owner can see): the email trend and the LinkedIn trend — each as { totals, series }, where totals is the exact whole-window figure per metric and series one zero-filled point per bucket — plus the top 10 LinkedIn campaigns by acceptance rate. Derive rates from totals (e.g. email open rate = cohortOpened / sent, LinkedIn acceptance rate = invitesAccepted / invitesSent); per-bucket rates must pair the cohort* fields with their own bucket's denominator. Buckets are daily for 7d and ISO-weekly for 30d and 90d; each point's date is its bucket's start date as a display label ('Jan 1') with the same date as YYYY-MM-DD in isoDate. Each panel is computed independently and is null when its aggregation fails, so always null-check them. Per-campaign detail stays on GET /business/campaigns/{campaignId}/stats. Rate limit: 20 requests per minute, 1000 per day.\n\nErrors:\n- `422` `VALIDATION_FAILED` — `range` was sent and is not one of 7d, 30d or 90d.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (20 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: analytics."
      }
    },
    "/business/analytics/dialer": {
      "get": {
        "operationId": "getDialerAnalytics",
        "summary": "Dialer analytics roll-up",
        "tags": [
          "Analytics"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "default": "30d",
              "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "range": {
                      "type": "string",
                      "enum": [
                        "7d",
                        "30d",
                        "90d"
                      ]
                    },
                    "campaigns": {
                      "type": "object",
                      "properties": {
                        "trend": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "totals": {
                              "type": "object",
                              "properties": {
                                "dialed": {
                                  "type": "integer"
                                },
                                "callsMade": {
                                  "type": "integer"
                                },
                                "answered": {
                                  "type": "integer"
                                },
                                "connected": {
                                  "type": "integer"
                                },
                                "connectedPositive": {
                                  "type": "integer"
                                },
                                "connectedNeutral": {
                                  "type": "integer"
                                },
                                "connectedNegative": {
                                  "type": "integer"
                                },
                                "connectedFollowUp": {
                                  "type": "integer"
                                },
                                "voicemailDropped": {
                                  "type": "integer"
                                },
                                "busy": {
                                  "type": "integer"
                                },
                                "noAnswer": {
                                  "type": "integer"
                                },
                                "badWrongNumber": {
                                  "type": "integer"
                                },
                                "dialable": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "dialed",
                                "callsMade",
                                "answered",
                                "connected",
                                "connectedPositive",
                                "connectedNeutral",
                                "connectedNegative",
                                "connectedFollowUp",
                                "voicemailDropped",
                                "busy",
                                "noAnswer",
                                "badWrongNumber",
                                "dialable"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "isoDate": {
                                    "type": "string"
                                  },
                                  "dialed": {
                                    "type": "integer"
                                  },
                                  "answered": {
                                    "type": "integer"
                                  },
                                  "connected": {
                                    "type": "integer"
                                  },
                                  "connectedPositive": {
                                    "type": "integer"
                                  },
                                  "connectedFollowUp": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "isoDate",
                                  "dialed",
                                  "answered",
                                  "connected",
                                  "connectedPositive",
                                  "connectedFollowUp"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totals",
                            "series"
                          ]
                        }
                      },
                      "required": [
                        "trend"
                      ]
                    },
                    "powerDialer": {
                      "type": "object",
                      "properties": {
                        "trend": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "totals": {
                              "type": "object",
                              "properties": {
                                "dialed": {
                                  "type": "integer"
                                },
                                "callsMade": {
                                  "type": "integer"
                                },
                                "answered": {
                                  "type": "integer"
                                },
                                "connected": {
                                  "type": "integer"
                                },
                                "connectedPositive": {
                                  "type": "integer"
                                },
                                "connectedNeutral": {
                                  "type": "integer"
                                },
                                "connectedNegative": {
                                  "type": "integer"
                                },
                                "connectedFollowUp": {
                                  "type": "integer"
                                },
                                "voicemailDropped": {
                                  "type": "integer"
                                },
                                "busy": {
                                  "type": "integer"
                                },
                                "noAnswer": {
                                  "type": "integer"
                                },
                                "badWrongNumber": {
                                  "type": "integer"
                                },
                                "dialable": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "dialed",
                                "callsMade",
                                "answered",
                                "connected",
                                "connectedPositive",
                                "connectedNeutral",
                                "connectedNegative",
                                "connectedFollowUp",
                                "voicemailDropped",
                                "busy",
                                "noAnswer",
                                "badWrongNumber",
                                "dialable"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "isoDate": {
                                    "type": "string"
                                  },
                                  "dialed": {
                                    "type": "integer"
                                  },
                                  "answered": {
                                    "type": "integer"
                                  },
                                  "connected": {
                                    "type": "integer"
                                  },
                                  "connectedPositive": {
                                    "type": "integer"
                                  },
                                  "connectedFollowUp": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "isoDate",
                                  "dialed",
                                  "answered",
                                  "connected",
                                  "connectedPositive",
                                  "connectedFollowUp"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totals",
                            "series"
                          ]
                        }
                      },
                      "required": [
                        "trend"
                      ]
                    }
                  },
                  "required": [
                    "range",
                    "campaigns",
                    "powerDialer"
                  ]
                },
                "example": {
                  "range": "30d",
                  "campaigns": {
                    "trend": {
                      "totals": {
                        "dialed": 57,
                        "callsMade": 68,
                        "answered": 21,
                        "connected": 12,
                        "connectedPositive": 4,
                        "connectedNeutral": 5,
                        "connectedNegative": 2,
                        "connectedFollowUp": 3,
                        "voicemailDropped": 9,
                        "busy": 4,
                        "noAnswer": 18,
                        "badWrongNumber": 2,
                        "dialable": 240
                      },
                      "series": [
                        {
                          "date": "Jul 27",
                          "isoDate": "2026-07-27",
                          "dialed": 30,
                          "answered": 11,
                          "connected": 7,
                          "connectedPositive": 2,
                          "connectedFollowUp": 2
                        },
                        {
                          "date": "Aug 3",
                          "isoDate": "2026-08-03",
                          "dialed": 29,
                          "answered": 10,
                          "connected": 5,
                          "connectedPositive": 2,
                          "connectedFollowUp": 1
                        }
                      ]
                    }
                  },
                  "powerDialer": {
                    "trend": {
                      "totals": {
                        "dialed": 84,
                        "callsMade": 103,
                        "answered": 33,
                        "connected": 19,
                        "connectedPositive": 6,
                        "connectedNeutral": 8,
                        "connectedNegative": 3,
                        "connectedFollowUp": 4,
                        "voicemailDropped": 14,
                        "busy": 6,
                        "noAnswer": 27,
                        "badWrongNumber": 3,
                        "dialable": 240
                      },
                      "series": [
                        {
                          "date": "Jul 27",
                          "isoDate": "2026-07-27",
                          "dialed": 44,
                          "answered": 17,
                          "connected": 11,
                          "connectedPositive": 3,
                          "connectedFollowUp": 3
                        },
                        {
                          "date": "Aug 3",
                          "isoDate": "2026-08-03",
                          "dialed": 42,
                          "answered": 16,
                          "connected": 8,
                          "connectedPositive": 3,
                          "connectedFollowUp": 1
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The dialer insights tab in one response: campaigns covers campaign-driven outbound dials (campaigns the token owner can see) and powerDialer covers every outbound dial the owner's team placed (campaign plus ad hoc); inbound calls are excluded from every metric. Each panel is { totals, series }. totals counts each contact once across the whole window with the full outcome breakdown, plus callsMade (raw call records) and dialable (distinct contacts enrolled in the campaign target lists — the campaign portion only); voicemailDropped counts contacts with at least one call whose voicemailDroppedAt timestamp is set. series carries one zero-filled point per bucket with the five charted contact counts, where dialed is the denominator for the other four. Do not sum the series for headline figures — a contact worked in two buckets counts once in totals but once per bucket in series. Granularity is daily for 7d and weekly for 30d and 90d; each point's date is its bucket's start date as a display label ('Jan 1') with the same date as YYYY-MM-DD in isoDate. Each panel is computed independently and is null when its aggregation fails. Rate limit: 20 requests per minute, 1000 per day.\n\nErrors:\n- `422` `VALIDATION_FAILED` — `range` was sent and is not one of 7d, 30d or 90d.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (20 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: analytics."
      }
    },
    "/business/analytics/enrichment": {
      "get": {
        "operationId": "getEnrichmentAnalytics",
        "summary": "Enrichment analytics roll-up",
        "tags": [
          "Analytics"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "default": "30d",
              "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "range": {
                      "type": "string",
                      "enum": [
                        "7d",
                        "30d",
                        "90d"
                      ]
                    },
                    "enrichment": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "emailsEnriched": {
                          "type": "object",
                          "properties": {
                            "totalSince": {
                              "type": "integer"
                            },
                            "mode": {
                              "type": "string",
                              "enum": [
                                "day",
                                "week"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "total": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "total"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totalSince",
                            "mode",
                            "series"
                          ]
                        },
                        "phonesEnriched": {
                          "type": "object",
                          "properties": {
                            "totalSince": {
                              "type": "integer"
                            },
                            "mode": {
                              "type": "string",
                              "enum": [
                                "day",
                                "week"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "total": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "total"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totalSince",
                            "mode",
                            "series"
                          ]
                        },
                        "contactsSaved": {
                          "type": "object",
                          "properties": {
                            "totalSince": {
                              "type": "integer"
                            },
                            "mode": {
                              "type": "string",
                              "enum": [
                                "day",
                                "week"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "total": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "total"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totalSince",
                            "mode",
                            "series"
                          ]
                        },
                        "contactsSearched": {
                          "type": "object",
                          "properties": {
                            "totalSince": {
                              "type": "integer"
                            },
                            "mode": {
                              "type": "string",
                              "enum": [
                                "day",
                                "week"
                              ]
                            },
                            "series": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "date": {
                                    "type": "string"
                                  },
                                  "total": {
                                    "type": "integer"
                                  }
                                },
                                "required": [
                                  "date",
                                  "total"
                                ]
                              }
                            }
                          },
                          "required": [
                            "totalSince",
                            "mode",
                            "series"
                          ]
                        }
                      },
                      "required": [
                        "emailsEnriched",
                        "phonesEnriched",
                        "contactsSaved",
                        "contactsSearched"
                      ]
                    }
                  },
                  "required": [
                    "range",
                    "enrichment"
                  ]
                },
                "example": {
                  "range": "30d",
                  "enrichment": {
                    "emailsEnriched": {
                      "totalSince": 644,
                      "mode": "week",
                      "series": [
                        {
                          "date": "W30",
                          "total": 5
                        },
                        {
                          "date": "W31",
                          "total": 141
                        },
                        {
                          "date": "W32",
                          "total": 63
                        },
                        {
                          "date": "W33",
                          "total": 89
                        },
                        {
                          "date": "W34",
                          "total": 263
                        },
                        {
                          "date": "W35",
                          "total": 83
                        }
                      ]
                    },
                    "phonesEnriched": {
                      "totalSince": 801,
                      "mode": "week",
                      "series": [
                        {
                          "date": "W30",
                          "total": 0
                        },
                        {
                          "date": "W31",
                          "total": 150
                        },
                        {
                          "date": "W32",
                          "total": 122
                        },
                        {
                          "date": "W33",
                          "total": 84
                        },
                        {
                          "date": "W34",
                          "total": 398
                        },
                        {
                          "date": "W35",
                          "total": 47
                        }
                      ]
                    },
                    "contactsSaved": {
                      "totalSince": 73250,
                      "mode": "week",
                      "series": [
                        {
                          "date": "W30",
                          "total": 5
                        },
                        {
                          "date": "W31",
                          "total": 10916
                        },
                        {
                          "date": "W32",
                          "total": 25118
                        },
                        {
                          "date": "W33",
                          "total": 29195
                        },
                        {
                          "date": "W34",
                          "total": 7381
                        },
                        {
                          "date": "W35",
                          "total": 635
                        }
                      ]
                    },
                    "contactsSearched": {
                      "totalSince": 3579,
                      "mode": "week",
                      "series": [
                        {
                          "date": "W30",
                          "total": 0
                        },
                        {
                          "date": "W31",
                          "total": 0
                        },
                        {
                          "date": "W32",
                          "total": 0
                        },
                        {
                          "date": "W33",
                          "total": 0
                        },
                        {
                          "date": "W34",
                          "total": 2977
                        },
                        {
                          "date": "W35",
                          "total": 602
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Data-enrichment insights for every user whose contacts the token owner can see: distinct contacts whose email was enriched, whose phone was enriched, that were saved, and prospects searched (derived from Prospect Search credit spend), each as a total for the window plus a zero-filled series. Buckets are daily (mode 'day', MM/DD labels) for 7d and ISO-weekly (mode 'week', labelled `Wnn` by ISO week number, e.g. W31) for 30d and 90d. enrichment is null when the aggregation fails. Rate limit: 20 requests per minute, 1000 per day.\n\nErrors:\n- `422` `VALIDATION_FAILED` — `range` was sent and is not one of 7d, 30d or 90d.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (20 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: analytics."
      }
    },
    "/business/analytics/website-intent": {
      "get": {
        "operationId": "getWebsiteIntentAnalytics",
        "summary": "Website intent analytics roll-up",
        "tags": [
          "Analytics"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "default": "30d",
              "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "range": {
                      "type": "string",
                      "enum": [
                        "7d",
                        "30d",
                        "90d"
                      ]
                    },
                    "metrics": {
                      "type": "object",
                      "properties": {
                        "totalVisits": {
                          "type": "integer"
                        },
                        "uniqueCompanies": {
                          "type": "integer"
                        },
                        "uniquePeople": {
                          "type": "integer"
                        },
                        "highConfidenceVisits": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "totalVisits",
                        "uniqueCompanies",
                        "uniquePeople",
                        "highConfidenceVisits"
                      ]
                    },
                    "timeSeries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string"
                          },
                          "companies": {
                            "type": "integer"
                          },
                          "people": {
                            "type": "integer"
                          }
                        },
                        "required": [
                          "date",
                          "companies",
                          "people"
                        ]
                      }
                    },
                    "topVisitors": {
                      "type": "object",
                      "properties": {
                        "companies": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "companyName": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companyWebsite": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companyIndustry": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companySize": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companyLinkedin": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "personName": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "personLinkedin": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "department": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "location": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "count": {
                                "type": "integer"
                              },
                              "lastVisitDate": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "confidenceInterval": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "enum": [
                                  "high",
                                  "moderate",
                                  "low",
                                  null
                                ]
                              },
                              "page": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "companyName",
                              "companyWebsite",
                              "companyIndustry",
                              "companySize",
                              "companyLinkedin",
                              "personName",
                              "personLinkedin",
                              "department",
                              "location",
                              "count",
                              "lastVisitDate",
                              "confidenceInterval",
                              "page"
                            ]
                          }
                        },
                        "people": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "companyName": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companyWebsite": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companyIndustry": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companySize": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "companyLinkedin": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "personName": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "personLinkedin": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "department": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "location": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "count": {
                                "type": "integer"
                              },
                              "lastVisitDate": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "confidenceInterval": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "enum": [
                                  "high",
                                  "moderate",
                                  "low",
                                  null
                                ]
                              },
                              "page": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "companyName",
                              "companyWebsite",
                              "companyIndustry",
                              "companySize",
                              "companyLinkedin",
                              "personName",
                              "personLinkedin",
                              "department",
                              "location",
                              "count",
                              "lastVisitDate",
                              "confidenceInterval",
                              "page"
                            ]
                          }
                        }
                      },
                      "required": [
                        "companies",
                        "people"
                      ]
                    }
                  },
                  "required": [
                    "range",
                    "metrics",
                    "timeSeries",
                    "topVisitors"
                  ]
                },
                "example": {
                  "range": "7d",
                  "metrics": {
                    "totalVisits": 1518,
                    "uniqueCompanies": 182,
                    "uniquePeople": 47,
                    "highConfidenceVisits": 206
                  },
                  "timeSeries": [
                    {
                      "date": "08/18",
                      "companies": 76,
                      "people": 13
                    },
                    {
                      "date": "08/19",
                      "companies": 68,
                      "people": 7
                    }
                  ],
                  "topVisitors": {
                    "companies": [
                      {
                        "companyName": "Rivian",
                        "companyWebsite": "rivian.com",
                        "companyIndustry": "Transportation",
                        "companySize": "10000+",
                        "companyLinkedin": "https://www.linkedin.com/company/rivian",
                        "personName": null,
                        "personLinkedin": null,
                        "department": "software",
                        "location": "united states",
                        "count": 624,
                        "lastVisitDate": "2026-08-25",
                        "confidenceInterval": "low",
                        "page": null
                      }
                    ],
                    "people": [
                      {
                        "companyName": "u.s. department of health and human services (hhs)",
                        "companyWebsite": "hhs.gov",
                        "companyIndustry": "Healthcare",
                        "companySize": "10000+",
                        "companyLinkedin": "https://www.linkedin.com/company/hhsgov",
                        "personName": "April Bowen",
                        "personLinkedin": "linkedin.com/in/april-bowen-worsley-6b156a32",
                        "department": "manufacturing",
                        "location": "united states",
                        "count": 212,
                        "lastVisitDate": "2026-08-23",
                        "confidenceInterval": "moderate",
                        "page": "/pricing"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Website intent insights for the token owner's team over the window: headline metrics (visits, distinct companies, distinct people and the high-confidence share), the zero-filled visitors-over-time series (daily MM/DD buckets for 7d, ISO-week Wxx buckets for 30d and 90d) and the top 10 visiting companies and people by visit count, in the same row shape as GET /business/website-visitors. Needs website tracking to be set up: an account with no tracking record answers 404. Rate limit: 20 requests per minute, 1000 per day.\n\nErrors:\n- `404` `WEBSITE_TRACKING_NOT_SET_UP` — This account has no website-tracking record (no Webtraffic entry, or the caller resolves to no team owner) — set website tracking up in the app first.\n- `422` `VALIDATION_FAILED` — `range` was sent and is not one of 7d, 30d or 90d.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (20 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: analytics."
      }
    },
    "/business/analytics/agents": {
      "get": {
        "operationId": "getAgentAnalytics",
        "summary": "Agents analytics roll-up",
        "tags": [
          "Analytics"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "range",
            "in": "query",
            "required": false,
            "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length.",
            "schema": {
              "type": "string",
              "enum": [
                "7d",
                "30d",
                "90d"
              ],
              "default": "30d",
              "description": "Rolling window ending now: 7d, 30d (default) or 90d, i.e. the roll-up covers the last 7, 30 or 90 days; time-series bucket sizes (daily, weekly, monthly) are chosen from the window length."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "range": {
                      "type": "string",
                      "enum": [
                        "7d",
                        "30d",
                        "90d"
                      ]
                    },
                    "agents": {
                      "type": "object",
                      "properties": {
                        "totals": {
                          "type": "object",
                          "properties": {
                            "totalAgents": {
                              "type": "integer"
                            },
                            "activeAgents": {
                              "type": "integer"
                            },
                            "totalProspects": {
                              "type": "integer"
                            },
                            "peopleProspects": {
                              "type": "integer"
                            },
                            "companyProspects": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "totalAgents",
                            "activeAgents",
                            "totalProspects",
                            "peopleProspects",
                            "companyProspects"
                          ]
                        },
                        "byType": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "monitorType": {
                                "type": "string"
                              },
                              "listType": {
                                "type": "string",
                                "enum": [
                                  "people",
                                  "company"
                                ]
                              },
                              "agentCount": {
                                "type": "integer"
                              },
                              "prospects": {
                                "type": "integer"
                              },
                              "maxContacts": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "monitorType",
                              "listType",
                              "agentCount",
                              "prospects",
                              "maxContacts"
                            ]
                          }
                        },
                        "byStatus": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "status": {
                                "type": "string",
                                "enum": [
                                  "active",
                                  "paused",
                                  "expired",
                                  "processing",
                                  "failed",
                                  "deleted",
                                  "initializing"
                                ]
                              },
                              "count": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "status",
                              "count"
                            ]
                          }
                        },
                        "prospectsOverTime": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string"
                              },
                              "people": {
                                "type": "integer"
                              },
                              "companies": {
                                "type": "integer"
                              }
                            },
                            "required": [
                              "date",
                              "people",
                              "companies"
                            ]
                          }
                        }
                      },
                      "required": [
                        "totals",
                        "byType",
                        "byStatus",
                        "prospectsOverTime"
                      ]
                    }
                  },
                  "required": [
                    "range",
                    "agents"
                  ]
                },
                "example": {
                  "range": "30d",
                  "agents": {
                    "totals": {
                      "totalAgents": 6,
                      "activeAgents": 4,
                      "totalProspects": 480,
                      "peopleProspects": 310,
                      "companyProspects": 170
                    },
                    "byType": [
                      {
                        "monitorType": "job_postings",
                        "listType": "company",
                        "agentCount": 2,
                        "prospects": 170,
                        "maxContacts": 500
                      },
                      {
                        "monitorType": "person_starting_new_job",
                        "listType": "people",
                        "agentCount": 4,
                        "prospects": 310,
                        "maxContacts": 1000
                      }
                    ],
                    "byStatus": [
                      {
                        "status": "active",
                        "count": 4
                      },
                      {
                        "status": "paused",
                        "count": 2
                      }
                    ],
                    "prospectsOverTime": [
                      {
                        "date": "08/23",
                        "people": 0,
                        "companies": 0
                      },
                      {
                        "date": "08/24",
                        "people": 12,
                        "companies": 5
                      },
                      {
                        "date": "08/25",
                        "people": 9,
                        "companies": 2
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Signal-agent (watcher) performance for the token owner's team, proxied from the agents service: totals (agents, active agents, prospects found split into people and companies), a breakdown by agent kind and list type, a breakdown by agent status (active, paused, initializing, expired, ...) and the prospects-found series (daily MM/DD buckets up to 31 days, ISO-week buckets labelled by their Monday for 90d). Only agents created inside the window are counted, together with the prospects those agents delivered. `byType[].monitorType` is the engine's own agent slug and is coarser than the `type` used to create agents: several slugs map to one public type. Rate limit: 20 requests per minute, 1000 per day.\n\nErrors:\n- `422` `VALIDATION_FAILED` — `range` was sent and is not one of 7d, 30d or 90d.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (20 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: analytics."
      }
    },
    "/business/website-visitors": {
      "get": {
        "operationId": "listWebsiteVisitors",
        "summary": "The deanonymized visitor feed",
        "tags": [
          "Website intent"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": true,
            "description": "Which feed to return: `people` (identified visitors, one row per person) or `companies` (visiting companies, one row per company); the feed is all-time, not windowed.",
            "schema": {
              "type": "string",
              "enum": [
                "people",
                "companies"
              ],
              "description": "Which feed to return: `people` (identified visitors, one row per person) or `companies` (visiting companies, one row per company); the feed is all-time, not windowed."
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "1-based page number, 1 to 10000 (default 1).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 10000,
              "default": 1,
              "description": "1-based page number, 1 to 10000 (default 1)."
            }
          },
          {
            "name": "pageSize",
            "in": "query",
            "required": false,
            "description": "Rows per page, 1 to 100 (default 20).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20,
              "description": "Rows per page, 1 to 100 (default 20)."
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Free text, 1 to 200 characters; there is no vocabulary to look up. Matched as a case-insensitive substring against exactly one column: the person's name when `type=people`, the company name when `type=companies` — the people feed never matches a company name, so searching a company there returns 0 rows. The value is interpolated into a SQL LIKE pattern without escaping, so `%` and `_` act as wildcards (`search=%` matches every row). Rows whose name was never resolved are excluded from both feeds whether or not `search` is sent. A value that matches nothing is not an error: the response is 200 with an empty `visitors` array.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "description": "Free text, 1 to 200 characters; there is no vocabulary to look up. Matched as a case-insensitive substring against exactly one column: the person's name when `type=people`, the company name when `type=companies` — the people feed never matches a company name, so searching a company there returns 0 rows. The value is interpolated into a SQL LIKE pattern without escaping, so `%` and `_` act as wildcards (`search=%` matches every row). Rows whose name was never resolved are excluded from both feeds whether or not `search` is sent. A value that matches nothing is not an error: the response is 200 with an empty `visitors` array."
            }
          },
          {
            "name": "sortBy",
            "in": "query",
            "required": false,
            "description": "Field to sort the feed by (default lastVisitDate); `count` is the visit count and `name` the identified person's name.",
            "schema": {
              "type": "string",
              "enum": [
                "lastVisitDate",
                "count",
                "companyName",
                "name",
                "companySize",
                "companyIndustry",
                "department",
                "location",
                "confidenceInterval"
              ],
              "default": "lastVisitDate",
              "description": "Field to sort the feed by (default lastVisitDate); `count` is the visit count and `name` the identified person's name."
            }
          },
          {
            "name": "sortOrder",
            "in": "query",
            "required": false,
            "description": "Sort direction, asc or desc (default desc).",
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ],
              "default": "desc",
              "description": "Sort direction, asc or desc (default desc)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "visitors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "companyName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "companyWebsite": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "companyIndustry": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "companySize": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "companyLinkedin": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "personName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "personLinkedin": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "department": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "location": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "count": {
                            "type": "integer"
                          },
                          "lastVisitDate": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "confidenceInterval": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "high",
                              "moderate",
                              "low",
                              null
                            ]
                          },
                          "page": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "companyName",
                          "companyWebsite",
                          "companyIndustry",
                          "companySize",
                          "companyLinkedin",
                          "personName",
                          "personLinkedin",
                          "department",
                          "location",
                          "count",
                          "lastVisitDate",
                          "confidenceInterval",
                          "page"
                        ]
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "page": {
                          "type": "integer"
                        },
                        "pageSize": {
                          "type": "integer"
                        },
                        "totalPages": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "total",
                        "page",
                        "pageSize",
                        "totalPages"
                      ]
                    }
                  },
                  "required": [
                    "visitors",
                    "pagination"
                  ]
                },
                "example": {
                  "visitors": [
                    {
                      "companyName": "Rivian",
                      "companyWebsite": "rivian.com",
                      "companyIndustry": "Transportation",
                      "companySize": "10000+",
                      "companyLinkedin": "https://www.linkedin.com/company/rivian",
                      "personName": null,
                      "personLinkedin": null,
                      "department": "software",
                      "location": "united states",
                      "count": 624,
                      "lastVisitDate": "2026-08-25",
                      "confidenceInterval": "low",
                      "page": null
                    },
                    {
                      "companyName": "u.s. department of health and human services (hhs)",
                      "companyWebsite": "hhs.gov",
                      "companyIndustry": "Healthcare",
                      "companySize": "10000+",
                      "companyLinkedin": "https://www.linkedin.com/company/hhsgov",
                      "personName": "April Bowen",
                      "personLinkedin": "linkedin.com/in/april-bowen-worsley-6b156a32",
                      "department": "manufacturing",
                      "location": "united states",
                      "count": 212,
                      "lastVisitDate": "2026-08-23",
                      "confidenceInterval": "moderate",
                      "page": "/pricing"
                    }
                  ],
                  "pagination": {
                    "total": 2875,
                    "page": 1,
                    "pageSize": 20,
                    "totalPages": 144
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The deanonymized visitor feed for the token owner's team (the Website Intent screen): `type=companies` returns one row per visiting company, `type=people` one row per identified person. Both feeds return the same row shape — company details, the identified person when there is one, the visit count, the last visit date (YYYY-MM-DD) and the resolver's confidence (high, moderate, low) — with null wherever a value is unknown. The feed is all-time, paged (pageSize up to 100, page up to 10000) and sorted by last visit by default; `search` matches the company name (companies) or the person's name (people). Needs website tracking to be set up: an account with no tracking record answers 404. Rate limit: 30 requests per minute, 2000 per day.\n\nErrors:\n- `404` `WEBSITE_TRACKING_NOT_SET_UP` — This account has no website-tracking record (no Webtraffic entry, or the caller resolves to no team owner) — set website tracking up in the app first.\n- `422` `VALIDATION_FAILED` — The request failed validation: `type` is missing or is not people/companies, or a query parameter is outside its declared values or bounds. Unknown query parameters are ignored, not rejected.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 2000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: intent."
      }
    },
    "/business/website-tracking": {
      "get": {
        "operationId": "getWebsiteTracking",
        "summary": "Tracking config: domains, pages, script, credit limit",
        "tags": [
          "Website intent"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tracking": {
                      "type": "object",
                      "properties": {
                        "domains": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "trackedPages": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "script": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "credits": {
                          "type": "object",
                          "properties": {
                            "limit": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "used": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "limit",
                            "used"
                          ]
                        }
                      },
                      "required": [
                        "domains",
                        "trackedPages",
                        "script",
                        "credits"
                      ]
                    }
                  },
                  "required": [
                    "tracking"
                  ]
                },
                "example": {
                  "tracking": {
                    "domains": [
                      "brightpay.com"
                    ],
                    "trackedPages": [
                      "pricing",
                      "home",
                      "product",
                      "faq"
                    ],
                    "script": "<script type=\"text/javascript\" src=\"https://a.usbrowserspeed.com/cs?pid=ddae2e0bce828a30a7b24f94f87290780f71120eaf9f11353f234c3bd86512d3&puid=%7B%22userId%22%3A%2268540f8bb55e99628170c757%22%2C%22env%22%3A%22dev%22%7D\"></script>",
                    "credits": {
                      "limit": 9999999,
                      "used": 1395
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The Settings > Website state in one response: the tracked domains and page paths, the HTML script tag to install in the site's head (null when the plan includes no website intent) and the monthly deanonymization credit budget — `credits.limit` is the monthly cap (null when uncapped) and `credits.used` the credits spent so far. An account that has never set tracking up reads back empty rather than 404. Rate limit: 30 requests per minute, 2000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 2000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: intent."
      },
      "patch": {
        "operationId": "updateWebsiteTracking",
        "summary": "Update tracked domains/pages or the monthly credit limit",
        "tags": [
          "Website intent"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tracking": {
                      "type": "object",
                      "properties": {
                        "domains": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "trackedPages": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "script": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "credits": {
                          "type": "object",
                          "properties": {
                            "limit": {
                              "type": [
                                "integer",
                                "null"
                              ]
                            },
                            "used": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "limit",
                            "used"
                          ]
                        }
                      },
                      "required": [
                        "domains",
                        "trackedPages",
                        "script",
                        "credits"
                      ]
                    }
                  },
                  "required": [
                    "tracking"
                  ]
                },
                "example": {
                  "tracking": {
                    "domains": [
                      "brightpay.com"
                    ],
                    "trackedPages": [
                      "pricing",
                      "home",
                      "product",
                      "faq"
                    ],
                    "script": "<script type=\"text/javascript\" src=\"https://a.usbrowserspeed.com/cs?pid=ddae2e0bce828a30a7b24f94f87290780f71120eaf9f11353f234c3bd86512d3&puid=%7B%22userId%22%3A%2268540f8bb55e99628170c757%22%2C%22env%22%3A%22dev%22%7D\"></script>",
                    "credits": {
                      "limit": 5000,
                      "used": 1395
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Update the tracked domains and page paths and/or the monthly deanonymization credit cap. Send at least one field. `domains` REPLACES the stored list (an empty array stops tracking) and `trackedPages` must be sent together with `domains`, because both ride one internal write that always sets the domain list. `monthlyCreditLimit` must not exceed the plan's credit allowance; send null to remove the cap. The response is the full tracking state after the write, identical to GET /business/website-tracking. Rate limit: 30 requests per minute, 2000 per day.\n\nErrors:\n- `404` `WEBSITE_TRACKING_NOT_SET_UP` — This account has no website-tracking record (no Webtraffic entry, or the caller resolves to no team owner) — set website tracking up in the app first.\n- `422` `VALIDATION_FAILED` — No field sent, `trackedPages` without `domains`, a value outside its bounds, or a credit cap Webtraffic rejected as not a whole non-negative number.\n- `422` `CREDIT_LIMIT_EXCEEDS_PLAN` — The requested monthly credit limit is higher than the plan's credit allowance.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 2000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: intent.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "domains": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 3,
                      "maxLength": 255
                    },
                    "minItems": 0,
                    "maxItems": 50,
                    "description": "Replacement list of the website domains you have installed the tracking tag on, 0 to 50 entries of 3 to 255 characters. You choose the values — there is no vocabulary endpoint; read the current list from `GET /business/website-tracking` (`tracking.domains`) and send it back with your edits, because the whole array replaces the stored list on every call and an omitted entry is dropped. Use the canonical form the app writes: a bare lower-case hostname with no scheme, path or port and with a leading `www.` removed, for example `brightpay.com` rather than `https://www.brightpay.com/pricing`. Entries are whitespace-trimmed by this API; case is preserved and duplicates are kept, so any other spelling is accepted and simply sits in the list unused. Entries do not combine into a query: this list records where the tag is installed and does not gate collection — visits are attributed by the `puid` inside the tag script, so editing or emptying this list neither starts nor stops tracking, only adding or removing the script from the page does."
                  },
                  "trackedPages": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 2048
                    },
                    "maxItems": 200,
                    "description": "Replacement list of the page labels you want reported separately, up to 200 entries of 1 to 2048 characters. These are free-text names you choose, not URL paths: the app writes short lower-case labels such as `pricing`, `home` or `product`, and the label is echoed back verbatim as `page` on each visitor row. There is no vocabulary endpoint; read the current list from `GET /business/website-tracking` (`tracking.trackedPages`) and send it back with your edits, because the whole array replaces the stored list on every call and an omitted entry is dropped. Entries are whitespace-trimmed by this API; case is preserved and duplicates are kept. Entries do not combine into a query: each names one page reported on its own, and a visitor row carries at most one label. A label only yields data once the matching per-page tag script is installed on that page (the label is embedded in that script's `puid`), so adding a name here on its own is accepted and reports nothing. Must be sent together with `domains` because both ride one internal write that always replaces the domain list."
                  },
                  "monthlyCreditLimit": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "minimum": 0,
                    "maximum": 10000000,
                    "description": "Cap on the credits spent deanonymising visitors in one billing period: any whole number of credits from 0 to 10000000, or `null` to remove the cap and fall back to the plan's own allowance. Not a vocabulary — every integer in range is a legal value. A cap above the credits on your active subscription is rejected with 422 `CREDIT_LIMIT_EXCEEDS_PLAN`; an account with no active subscription is not checked against a plan. The counter it caps (`tracking.credits.used`) resets at the start of each billing period on monthly plans, and every 30 days or on renewal on annual plans. `0` stops deanonymisation until the cap is raised."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/business/accounts": {
      "get": {
        "operationId": "listAccounts",
        "summary": "Connected sending accounts by channel",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "channel",
            "in": "query",
            "required": true,
            "description": "Sending channel to list: `email` (connected mailboxes: gmail, outlook or smtp) or `linkedin` (connected LinkedIn seats); the row shape differs per channel.",
            "schema": {
              "type": "string",
              "enum": [
                "email",
                "linkedin"
              ],
              "description": "Sending channel to list: `email` (connected mailboxes: gmail, outlook or smtp) or `linkedin` (connected LinkedIn seats); the row shape differs per channel."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "channel": {
                      "type": "string",
                      "enum": [
                        "email",
                        "linkedin"
                      ]
                    },
                    "accounts": {
                      "type": "array",
                      "items": {
                        "anyOf": [
                          {
                            "type": "object",
                            "title": "EmailAccount",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "emailAddress": {
                                "type": "string"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "provider": {
                                "type": "string",
                                "enum": [
                                  "gmail",
                                  "outlook",
                                  "smtp"
                                ]
                              },
                              "isActive": {
                                "type": "boolean"
                              },
                              "isConnected": {
                                "type": "boolean"
                              },
                              "dailyCapacity": {
                                "type": "integer"
                              },
                              "availableCapacity": {
                                "type": "integer"
                              },
                              "needsReauthAt": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "needsReauthReason": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "emailAddress",
                              "name",
                              "provider",
                              "isActive",
                              "isConnected",
                              "dailyCapacity",
                              "availableCapacity",
                              "needsReauthAt",
                              "needsReauthReason"
                            ]
                          },
                          {
                            "type": "object",
                            "title": "LinkedInAccount",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "email": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "publicIdentifier": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "type": {
                                "type": "string"
                              },
                              "isActive": {
                                "type": "boolean"
                              },
                              "isConnected": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "id",
                              "name",
                              "email",
                              "publicIdentifier",
                              "type",
                              "isActive",
                              "isConnected"
                            ]
                          }
                        ]
                      }
                    }
                  },
                  "required": [
                    "channel",
                    "accounts"
                  ]
                },
                "example": {
                  "channel": "email",
                  "accounts": [
                    {
                      "id": "sam@brightpay.com",
                      "emailAddress": "sam@brightpay.com",
                      "name": "Sam Rivera",
                      "provider": "gmail",
                      "isActive": true,
                      "isConnected": true,
                      "dailyCapacity": 30,
                      "availableCapacity": 29,
                      "needsReauthAt": null,
                      "needsReauthReason": null
                    },
                    {
                      "id": "outreach@brightpay.com",
                      "emailAddress": "outreach@brightpay.com",
                      "name": null,
                      "provider": "smtp",
                      "isActive": true,
                      "isConnected": false,
                      "dailyCapacity": 15,
                      "availableCapacity": 15,
                      "needsReauthAt": "2026-08-17T16:22:52.131Z",
                      "needsReauthReason": "smtp_auth_rejected"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The connected sending accounts for one channel. `channel=email` lists the mailboxes the token owner owns or has shared with them: `id` is the email address (use it as a campaign sender), `provider` is gmail, outlook or smtp, and needsReauthAt/needsReauthReason are set when the provider invalidated the connection. `channel=linkedin` lists the owner's LinkedIn seats: `id` is the LinkedIn account id accepted by `linkedin_sender_account_ids`, `type` is the LinkedIn plan (classic or a premium variant). Available to any valid key (no scope needed). Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `422` `VALIDATION_FAILED` — `channel` is missing (it is required) or is not email or linkedin.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day); retry after the Retry-After / RateLimit-Reset seconds."
      }
    },
    "/business/team/members": {
      "get": {
        "operationId": "listTeamMembers",
        "summary": "Teammates (id, name, email)",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "members": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "email",
                          "name"
                        ]
                      }
                    }
                  },
                  "required": [
                    "members"
                  ]
                },
                "example": {
                  "members": [
                    {
                      "id": "68540f8bb55e99628170c757",
                      "email": "sam@brightpay.com",
                      "name": "Sam Rivera"
                    },
                    {
                      "id": "6a46c773cb58be863495ae51",
                      "email": "ada@brightpay.com",
                      "name": "Ada Nwosu"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The active members of the token owner's team (the owner included), up to 100, with the user id, email and display name. Use `id` in `delegates` on campaigns and agents (they also accept plain emails). Available to any valid key (no scope needed). Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day); retry after the Retry-After / RateLimit-Reset seconds."
      }
    },
    "/business/writing-styles": {
      "get": {
        "operationId": "listWritingStyles",
        "summary": "The writing styles AI campaigns accept",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "writingStyles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "isDefault": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "isDefault"
                        ]
                      }
                    }
                  },
                  "required": [
                    "writingStyles"
                  ]
                },
                "example": {
                  "writingStyles": [
                    {
                      "id": "68a1fd309c41d20014b3f401",
                      "name": "Default writing style",
                      "isDefault": true
                    },
                    {
                      "id": "68a1fd309c41d20014b3f402",
                      "name": "Strict Corporate",
                      "isDefault": false
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The token owner's writing styles, default first then most recently updated; a default style is created on first access. Use `id` as `writingStyleId` when creating an AI campaign. Available to any valid key (no scope needed). Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day); retry after the Retry-After / RateLimit-Reset seconds."
      }
    },
    "/business/integrations": {
      "get": {
        "operationId": "listIntegrations",
        "summary": "Which CRMs the team has connected",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "integrations": {
                      "type": "object",
                      "properties": {
                        "crm": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "hubspot",
                            "salesforce",
                            "attio",
                            "zoho",
                            "pipedrive",
                            null
                          ]
                        },
                        "connected": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "hubspot",
                              "salesforce",
                              "attio",
                              "zoho",
                              "pipedrive"
                            ]
                          }
                        }
                      },
                      "required": [
                        "crm",
                        "connected"
                      ]
                    }
                  },
                  "required": [
                    "integrations"
                  ]
                },
                "example": {
                  "integrations": {
                    "crm": "hubspot",
                    "connected": [
                      "hubspot"
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Which CRM the token owner's team has connected: `crm` is hubspot, salesforce, attio, zoho or pipedrive (the first one found in that order across the team's active members) or null when none is connected, and `connected` lists the connected CRM identifiers. Check it before POST /business/lists/{listId}/crm-push, which answers 422 CRM_NOT_CONNECTED for an unconnected CRM. Available to any valid key (no scope needed). Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day); retry after the Retry-After / RateLimit-Reset seconds."
      }
    },
    "/business/jobs/{jobId}": {
      "get": {
        "operationId": "getJob",
        "summary": "Poll any async job",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of an async job, as returned with the 202 that started it (POST /business/lists/{listId}/export).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of an async job, as returned with the 202 that started it (POST /business/lists/{listId}/export)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {
                      "type": "object",
                      "properties": {
                        "jobId": {
                          "type": "string"
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "list_export",
                            "web_monitor_run_ingest",
                            "bulk_enrichment",
                            null
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "processing",
                            "completed",
                            "failed",
                            "stopped",
                            "cancelled"
                          ]
                        },
                        "rowCount": {
                          "type": [
                            "integer",
                            "null"
                          ]
                        },
                        "downloadUrl": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "error": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "listIds": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "bulk_enrichment only: the lists the run fills."
                        },
                        "progress": {
                          "type": "object",
                          "description": "bulk_enrichment only: the run's counts so far.",
                          "properties": {
                            "totalContacts": {
                              "type": "integer"
                            },
                            "processedContacts": {
                              "type": "integer"
                            },
                            "enrichedContacts": {
                              "type": "integer"
                            },
                            "notFoundContacts": {
                              "type": "integer"
                            },
                            "alreadyEnrichedContacts": {
                              "type": "integer"
                            },
                            "creditsCharged": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "totalContacts",
                            "processedContacts",
                            "enrichedContacts",
                            "notFoundContacts",
                            "alreadyEnrichedContacts",
                            "creditsCharged"
                          ]
                        },
                        "pausedReason": {
                          "type": "string",
                          "enum": [
                            "INSUFFICIENT_CREDITS"
                          ],
                          "description": "bulk_enrichment only, when status is stopped: why the run paused."
                        }
                      },
                      "required": [
                        "jobId",
                        "type",
                        "status",
                        "rowCount",
                        "downloadUrl",
                        "error"
                      ]
                    }
                  },
                  "required": [
                    "job"
                  ]
                },
                "example": {
                  "job": {
                    "jobId": "68a2109c9c41d20014b41001",
                    "type": "list_export",
                    "status": "completed",
                    "rowCount": 1240,
                    "downloadUrl": "https://fuse-list-exports.s3.eu-west-1.amazonaws.com/exports/68a2109c9c41d20014b41001/export.csv?response-content-disposition=attachment%3B%20filename%3D%22European_fintech_Series_A.csv%22&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Signature=3f6f0e2a8c1d4b7e9a2f5d6e7f8a9b0c",
                    "error": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Poll a CRM async job by the 24-hex id returned with a 202 (list exports via POST /business/lists/{listId}/export, GET /business/exports/{jobId} is an alias). `status` moves pending > processing > completed or failed; poll every few seconds until it is terminal. On completed, `rowCount` and a short-lived presigned `downloadUrl` (regenerated on every poll) are set; on failed, `error` carries the reason. A list or search enrichment's job (the `jobId` from POST /business/lists/{listId}/enrich or POST /business/prospects/search/save-to-list) has type `bulk_enrichment` and also carries `listIds` and `progress`: `status` is pending while it waits behind your other enrichment job, then processing, and ends completed, cancelled or failed (`error` ENRICHMENT_FAILED); stopped means it paused because the balance ran out (`pausedReason` INSUFFICIENT_CREDITS) and resumes from the app. Research runs, smart columns, imports and list processing have their own status endpoints and are not served here. Available to any valid key (no scope needed). Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `404` `JOB_NOT_FOUND` — No async job with that id belongs to the token owner (or it has expired).\n- `422` `VALIDATION_FAILED` — `jobId` is not a 24-character hex id — an import's UUID job id is not pollable here.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day, shared with the list endpoints); retry after the Retry-After / RateLimit-Reset seconds."
      }
    },
    "/business/credits/usage": {
      "post": {
        "operationId": "getCreditsUsage",
        "summary": "The credit spend ledger",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "since": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "to": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "memberIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "usage": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "properties": {
                        "used": {
                          "type": "integer"
                        },
                        "available": {
                          "type": "integer"
                        },
                        "total": {
                          "type": "integer"
                        },
                        "periodStartDate": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "periodEndDate": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "oneTimeCreditsHoldback": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "properties": {
                            "heldCredits": {
                              "type": "integer"
                            },
                            "releaseAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          },
                          "required": [
                            "heldCredits",
                            "releaseAt"
                          ]
                        }
                      },
                      "required": [
                        "used",
                        "available",
                        "total",
                        "periodStartDate",
                        "periodEndDate",
                        "oneTimeCreditsHoldback"
                      ]
                    },
                    "spendByDateByProduct": {
                      "type": [
                        "array",
                        "null"
                      ],
                      "items": {
                        "type": "object",
                        "properties": {
                          "date": {
                            "type": "string"
                          },
                          "isoDate": {
                            "type": "string",
                            "format": "date"
                          },
                          "products": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "product": {
                                  "type": "string",
                                  "enum": [
                                    "Phone Enrichment",
                                    "Email Enrichment",
                                    "Email Validation",
                                    "Email Warmup",
                                    "Website Traffic",
                                    "AI Engagement",
                                    "Call Recording & Transcripts",
                                    "Fuse Agent Message",
                                    "Saving to List",
                                    "Buying Domains",
                                    "Buying Mailboxes",
                                    "Charging Mailbox Subscription",
                                    "Charging Domain Subscription",
                                    "Charging LinkedIn Account Subscription",
                                    "Prospect Search",
                                    "Company Search",
                                    "Global Phone Number Search",
                                    "Phone Number Rent",
                                    "Signal Monitor Webhook",
                                    "People Watcher Setup",
                                    "Companies Watcher Setup",
                                    "Companies Watcher Recurring",
                                    "People Watcher Recurring",
                                    "Smart Column Enrichment",
                                    "Job Changes Watcher Delivery",
                                    "Web Monitor Result",
                                    "Deep Research Action",
                                    "Automation Run"
                                  ]
                                },
                                "value": {
                                  "type": "integer"
                                }
                              },
                              "required": [
                                "product",
                                "value"
                              ]
                            }
                          }
                        },
                        "required": [
                          "date",
                          "isoDate",
                          "products"
                        ]
                      }
                    }
                  },
                  "required": [
                    "since",
                    "to",
                    "memberIds",
                    "usage",
                    "spendByDateByProduct"
                  ]
                },
                "example": {
                  "since": "2026-09-01T00:00:00.000Z",
                  "to": null,
                  "memberIds": [],
                  "usage": {
                    "used": 5230,
                    "available": 14770,
                    "total": 20000,
                    "periodStartDate": "2026-08-14T18:30:00.000Z",
                    "periodEndDate": "2026-09-15T18:29:59.999Z",
                    "oneTimeCreditsHoldback": null
                  },
                  "spendByDateByProduct": [
                    {
                      "date": "Sep 1",
                      "isoDate": "2026-09-01",
                      "products": [
                        {
                          "product": "Email Enrichment",
                          "value": 396
                        },
                        {
                          "product": "Prospect Search",
                          "value": 90
                        }
                      ]
                    },
                    {
                      "date": "Sep 2",
                      "isoDate": "2026-09-02",
                      "products": []
                    },
                    {
                      "date": "Sep 3",
                      "isoDate": "2026-09-03",
                      "products": [
                        {
                          "product": "Deep Research Action",
                          "value": 660
                        },
                        {
                          "product": "Email Enrichment",
                          "value": 366
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The credit spend ledger for a `since` / `to` window (`to` omitted = up to now) and an optional `memberIds` teammate filter — the same contract as the internal spend endpoint, all echoed back (`to` as null and `memberIds` as [] when omitted): `usage` is the current billing period's headline (used, available, total, period bounds, and the AppSumo one-time holdback when one applies), and `spendByDateByProduct` is the zero-filled spend series over the window, each point carrying its deductions split by product. Points are time buckets sized by the window's length — daily while it spans at most 13 days, otherwise weekly (ISO weeks), monthly or quarterly — so a one-month window comes back by week and a one-year window by month. Each point carries `isoDate` (the bucket's start day, YYYY-MM-DD UTC) and `date` (a display label for that start: `Sep 1` for daily and weekly buckets, `Sep` for monthly, `Sep 2026` for quarterly). Sum a point's products for the bucket's total; sum a product across points for its window total. Omit `memberIds` (or pass `[]`) for the whole ledger; pass teammate ids to restrict the series to those people's deductions, including the owner id for the owner's own untagged charges. Each of the two panels is null when its lookup fails. Available to any valid key (no scope needed). Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `403` `TEAM_MEMBER_NOT_IN_SCOPE` — A `memberIds` entry is not an active member of the caller's team.\n- `422` `VALIDATION_FAILED` — `since` is missing or not an ISO 8601 date, `to` is not an ISO 8601 date or precedes `since`, or a `memberIds` entry is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day); retry after the Retry-After / RateLimit-Reset seconds.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "since": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Start of the spend window (inclusive) as an ISO 8601 date or date-time, e.g. 2026-08-01 or 2026-08-01T00:00:00Z. `spendByDateByProduct` is bucketed by the window's length — daily while it spans at most 13 days, then weekly (ISO weeks), monthly or quarterly — while `usage` always reflects the current billing period regardless of the window."
                  },
                  "to": {
                    "type": "string",
                    "format": "date-time",
                    "description": "End of the spend window (inclusive) as an ISO 8601 date or date-time; must not precede `since`. Omit to run the window up to now. A date-only value means midnight UTC at the START of that day, so send an end-of-day instant (e.g. 2026-08-31T23:59:59.999Z) to include the last day."
                  },
                  "memberIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 200,
                    "description": "Restrict `spendByDateByProduct` to these teammates' deductions. Omit or pass `[]` for the whole ledger (every teammate sees the same default). Each id must be an active member of the caller's team; including the owner adds the owner's own untagged charges. Any id outside the team answers 403 `TEAM_MEMBER_NOT_IN_SCOPE`. `usage` always reflects the current billing period regardless of this filter."
                  }
                },
                "required": [
                  "since"
                ]
              }
            }
          }
        }
      }
    },
    "/business/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Get the token owner's identity",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "user": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "email": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "email",
                        "name"
                      ]
                    }
                  },
                  "required": [
                    "user"
                  ]
                },
                "example": {
                  "user": {
                    "id": "685409d3287883fbc17c0ced",
                    "email": "ada@brightpay.com",
                    "name": "Ada Nwosu"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The identity of the user who owns the API token: user id, email and display name. Handy as a connectivity check because it needs no scope and is exempt from scope enforcement. Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day); retry after the Retry-After / RateLimit-Reset seconds."
      }
    },
    "/business/credits": {
      "get": {
        "operationId": "getCredits",
        "summary": "Get the token owner's credit balance",
        "tags": [
          "Account"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "balance": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "balance"
                  ]
                },
                "example": {
                  "balance": 8250
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The credits currently available to the token owner. Team members draw on the owner's pool, so a member sees the smaller of their remaining personal cap and the owner's balance. Billable calls answer 402 INSUFFICIENT_CREDITS when this reaches zero. Available to any valid key (no scope needed). Rate limit: 120 requests per minute, 10000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (120 per minute, 10000 per day); retry after the Retry-After / RateLimit-Reset seconds."
      }
    },
    "/business/prospects/filter-options": {
      "get": {
        "operationId": "getProspectFilterOptions",
        "summary": "Get the accepted prospect-search filter values",
        "tags": [
          "Prospect search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "filterOptions"
                  ],
                  "properties": {
                    "filterOptions": {
                      "type": "object",
                      "required": [
                        "fields",
                        "jobTitleRoleToSubRole"
                      ],
                      "properties": {
                        "fields": {
                          "type": "object",
                          "description": "One entry per search field, keyed by field name.",
                          "additionalProperties": {
                            "type": "object",
                            "required": [
                              "valueShape",
                              "values"
                            ],
                            "properties": {
                              "valueShape": {
                                "type": "string",
                                "enum": [
                                  "include_exclude",
                                  "include_exclude_or_string",
                                  "term"
                                ]
                              },
                              "values": {
                                "type": "array",
                                "description": "Accepted values; empty for free-text fields.",
                                "items": {
                                  "type": "object",
                                  "required": [
                                    "label",
                                    "value"
                                  ],
                                  "properties": {
                                    "label": {
                                      "type": "string"
                                    },
                                    "value": {
                                      "type": "string"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "jobTitleRoleToSubRole": {
                          "type": "object",
                          "description": "Each `job_title_role` value mapped to its `job_title_sub_role` values.",
                          "additionalProperties": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "filterOptions": {
                    "fields": {
                      "job_title_levels": {
                        "valueShape": "include_exclude",
                        "values": [
                          {
                            "label": "CXO",
                            "value": "cxo"
                          },
                          {
                            "label": "Director",
                            "value": "director"
                          },
                          {
                            "label": "Entry",
                            "value": "entry"
                          },
                          {
                            "label": "Manager",
                            "value": "manager"
                          },
                          {
                            "label": "Owner",
                            "value": "owner"
                          },
                          {
                            "label": "Partner",
                            "value": "partner"
                          },
                          {
                            "label": "Senior",
                            "value": "senior"
                          },
                          {
                            "label": "Training",
                            "value": "training"
                          },
                          {
                            "label": "Unpaid",
                            "value": "unpaid"
                          },
                          {
                            "label": "VP",
                            "value": "vp"
                          }
                        ]
                      },
                      "job_company_name": {
                        "valueShape": "include_exclude_or_string",
                        "values": []
                      },
                      "job_title": {
                        "valueShape": "term",
                        "values": []
                      },
                      "sex": {
                        "valueShape": "term",
                        "values": [
                          {
                            "label": "Female",
                            "value": "female"
                          },
                          {
                            "label": "Male",
                            "value": "male"
                          }
                        ]
                      }
                    },
                    "jobTitleRoleToSubRole": {
                      "advisory": [
                        "advisor",
                        "board_member",
                        "investor"
                      ],
                      "finance": [
                        "accounting",
                        "bookkeeping",
                        "planning_and_analysis",
                        "procurement",
                        "risk"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The whole people-search filter contract, keyed by search field name. `fields.<field>.valueShape` says how that field's value must be shaped on the wire — `include_exclude` takes `[{ status, value }]` entries, `include_exclude_or_string` takes entries or a bare string / array of strings (bare strings are includes), `term` takes a string or an array of strings — and `fields.<field>.values` lists the accepted `{ label, value }` pairs (send `value`). Free-text fields such as `job_title` or `location_name` have no vocabulary and come back with `values: []`; use GET /prospects/autocomplete for those. `jobTitleRoleToSubRole` maps every `job_title_role` to the `job_title_sub_role` values beneath it. A static vocabulary generated from the provider's schema: no tenant data, no credits, and callable with any valid token regardless of scope. Values outside a field's vocabulary match nothing, so POST /prospects/search rejects them with 422 before anything is billed.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure."
      }
    },
    "/business/prospects/autocomplete": {
      "get": {
        "operationId": "autocompleteProspectSearchField",
        "summary": "Suggest values for a free-text search field",
        "tags": [
          "Prospect search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "field",
            "in": "query",
            "required": true,
            "description": "Which free-text vocabulary to suggest from: `company`, `website`, `location`, `region`, `title`, `school` or `skill` (`region` suggestions also carry the `countries` they appear in).",
            "schema": {
              "type": "string",
              "enum": [
                "company",
                "website",
                "location",
                "region",
                "title",
                "school",
                "skill"
              ],
              "description": "Which free-text vocabulary to suggest from: `company`, `website`, `location`, `region`, `title`, `school` or `skill` (`region` suggestions also carry the `countries` they appear in)."
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Text fragment to complete (1-100 chars).",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100,
              "description": "Text fragment to complete (1-100 chars)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "field",
                    "suggestions"
                  ],
                  "properties": {
                    "field": {
                      "type": "string",
                      "enum": [
                        "company",
                        "website",
                        "location",
                        "region",
                        "title",
                        "school",
                        "skill"
                      ],
                      "description": "Echo of the requested field."
                    },
                    "suggestions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "name"
                        ],
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "The canonical value to send as the filter value."
                          },
                          "countries": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Only on `field=region` rows: the countries this region name appears in, likeliest first."
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "field": "region",
                  "suggestions": [
                    {
                      "name": "california",
                      "countries": [
                        "united states"
                      ]
                    },
                    {
                      "name": "baja california",
                      "countries": [
                        "mexico"
                      ]
                    },
                    {
                      "name": "baja california sur",
                      "countries": [
                        "mexico"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Type-ahead vocabulary for the free-text people filters — `company`, `website`, `location`, `region`, `title`, `school`, `skill` — the same suggestions the product's search UI offers. Send the returned `name` verbatim as the filter value; the values are lower-cased exactly as the provider stores them. The enum-backed fields are served in full by GET /prospects/filter-options instead. Only `field=region` rows carry `countries`, listing the countries that region name appears in, likeliest first, so identically named regions can be told apart. Free: no credits, no provider spend beyond the type-ahead call.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search."
      }
    },
    "/business/prospects/search": {
      "post": {
        "operationId": "searchProspects",
        "summary": "Run a people search",
        "tags": [
          "Prospect search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "profiles",
                    "scrollToken",
                    "total",
                    "filters"
                  ],
                  "properties": {
                    "profiles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "required": [
                          "linkedinConnectedAccountIds",
                          "linkedinInvitationSentAccountIds"
                        ],
                        "properties": {
                          "_id": {
                            "type": "string",
                            "description": "Fuse's own id for the cached person record; stable across searches and the id `savedProfile` refers to. Absent on a row the cache could not store."
                          },
                          "pdlId": {
                            "type": "string",
                            "description": "The provider's person id; always present — on a row the cache could not store it is the only id the row carries."
                          },
                          "savedProfile": {
                            "type": "boolean",
                            "description": "Whether this person is already a contact in one of your lists. Absent on a row the cache could not store, which cannot be matched against your contacts."
                          },
                          "savedBy": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Id of the workspace member who saved the contact; null when it is not saved, absent on a row the cache could not store."
                          },
                          "linkedinConnectedAccountIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Ids of your connected LinkedIn accounts already connected to this person."
                          },
                          "linkedinInvitationSentAccountIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Ids of your connected LinkedIn accounts that have already sent this person an invitation."
                          },
                          "linkedin_url": {
                            "type": "string"
                          },
                          "full_name": {
                            "type": "string"
                          },
                          "sex": {
                            "type": "string"
                          },
                          "industry": {
                            "type": "string"
                          },
                          "job_title": {
                            "type": "string"
                          },
                          "job_title_role": {
                            "type": "string"
                          },
                          "job_title_sub_role": {
                            "type": "string"
                          },
                          "job_title_class": {
                            "type": "string"
                          },
                          "job_title_levels": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "job_company_name": {
                            "type": "string"
                          },
                          "job_company_website": {
                            "type": "string"
                          },
                          "location_name": {
                            "type": "string"
                          },
                          "profile_score": {
                            "type": "string",
                            "description": "Provider signal string (e.g. \"positive signals\"); provider-driven, so not on every row."
                          },
                          "activity_score": {
                            "type": "string",
                            "description": "Provider signal string (e.g. \"positive signals\"); provider-driven, so not on every row."
                          },
                          "dataset_version": {
                            "type": "string"
                          },
                          "pdl_version": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "job_change_detected_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "scrollToken": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Send back as `scrollToken` with the same filter source to fetch the next page; null when the provider returned no continuation."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of people matching the filters, not the page size."
                    },
                    "filters": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The RESOLVED filters the search actually ran, in the POST /prospects/search vocabulary."
                    },
                    "ignoredFilterKeys": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Only when the source was a saved search: stored keys with no equivalent search field, which were dropped."
                    },
                    "unresolvedCriteria": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Only when the source was `query`: criteria in the prose that could not be turned into a filter."
                    }
                  }
                },
                "example": {
                  "profiles": [
                    {
                      "_id": "6a8dde1f5792025bcc9e9f61",
                      "pdlId": "gAkE2YBBdEZJ1b2iSrUKCQ_0000",
                      "linkedin_url": "linkedin.com/in/chrismumford",
                      "dataset_version": "35.1",
                      "pdl_version": "35.1",
                      "job_change_detected_at": null,
                      "createdAt": "2026-08-25T18:25:35.591Z",
                      "updatedAt": "2026-08-25T18:46:35.308Z",
                      "full_name": "chris mumford",
                      "sex": "male",
                      "industry": "real estate",
                      "job_title": "chief marketing officer - marketplaces",
                      "job_title_role": "marketing",
                      "job_title_class": "sales_and_marketing",
                      "job_title_levels": [
                        "cxo"
                      ],
                      "job_company_name": "costar group",
                      "job_company_website": "costargroup.com",
                      "location_name": "richmond, virginia, united states",
                      "profile_score": "positive signals",
                      "activity_score": "positive signals",
                      "savedProfile": false,
                      "savedBy": null,
                      "linkedinConnectedAccountIds": [],
                      "linkedinInvitationSentAccountIds": []
                    },
                    {
                      "_id": "6a8de30b1ea5e58766c32c42",
                      "pdlId": "aNNNUa3WaybVUGXWxsXcLw_0000",
                      "createdAt": "2026-08-25T18:46:35.293Z",
                      "updatedAt": "2026-08-25T18:46:35.293Z",
                      "full_name": "jack garnett",
                      "sex": "male",
                      "linkedin_url": "linkedin.com/in/jack-garnett-049b21a",
                      "industry": "commercial real estate",
                      "job_title": "president",
                      "job_title_role": "operations",
                      "job_title_sub_role": "executive",
                      "job_title_class": "general_and_administrative",
                      "job_title_levels": [
                        "cxo"
                      ],
                      "job_company_name": "costar group",
                      "job_company_website": "costargroup.com",
                      "location_name": "jacksonville, florida, united states",
                      "profile_score": "positive signals",
                      "activity_score": "positive signals",
                      "dataset_version": "35.1",
                      "pdl_version": "35.1",
                      "savedProfile": false,
                      "savedBy": null,
                      "linkedinConnectedAccountIds": [],
                      "linkedinInvitationSentAccountIds": []
                    }
                  ],
                  "scrollToken": "22116$3.0004656",
                  "total": 8,
                  "filters": {
                    "job_title_levels": [
                      {
                        "status": "include",
                        "value": "cxo"
                      }
                    ],
                    "location_country": [
                      {
                        "status": "include",
                        "value": "united states"
                      }
                    ],
                    "job_company_name": "costar group"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Run a people search. The filter source is exactly one of: literal `filters`, a stored PEOPLE saved search (`savedSearchId` or `savedSearchName`), or a natural-language `query` (the product's smart search converts the prose into filters; criteria it could not map come back as `unresolvedCriteria`). Sending two sources is a 422. A saved search resolves to its filters and echoes `ignoredFilterKeys` for stored keys with no search field; a company saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH.\n\nThe response always echoes the RESOLVED `filters` — reuse them verbatim to page, refine, or POST /prospects/search/save-to-list — plus the true match `total` and a `scrollToken` for the next page (send it back with the same filter source; it is null when there is no continuation).\n\nRows are the provider's person record in snake_case, so the fields present vary by person, plus Fuse's own keys: `pdlId` (the provider's person id; absent on the rare row the profile cache could not store), `_id` (our stable id for the cached person record, present unless that row could not be cached), `savedProfile` / `savedBy` (whether this person is already a contact of yours), and `linkedinConnectedAccountIds` / `linkedinInvitationSentAccountIds` (which of your connected LinkedIn accounts already reached them). Rows carry no email address or phone number — searching is discovery only. Contact details you have already enriched for some of these people are stripped too, so a row never depends on your enrichment history; use /prospects/search/save-to-list with `enrich` to obtain contact details.\n\nBilling: 2 credits per requested profile are pre-checked and 2 credits per profile returned are debited. (Enforced by the public row transformer, which removes Fuse's enrichment overlay and the provider's own work_email, personal_emails, recommended_personal_email, mobile_phone and phone_numbers before the row is returned.)\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — The balance does not cover the pre-check for this request; nothing was billed.\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id or exact title.\n- `409` `SAVED_SEARCH_NAME_AMBIGUOUS` — Two of your saved searches share that title — reference it by `savedSearchId` instead.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `422` `SAVED_SEARCH_TYPE_MISMATCH` — The saved search exists but stores the other kind of filters; `param` is `savedSearchId`.\n- `422` `SAVED_SEARCH_INVALID` — The STORED filters no longer form a runnable search — every value was retired, or the blob translates to nothing.\n- `422` `QUERY_FILTERS_INVALID` — The natural-language `query` produced no usable filter; name concrete criteria.\n- `422` `SEARCH_FILTERS_INVALID` — The provider rejected the assembled query as malformed — a filter value is the wrong shape for its field.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "properties": {
                      "industry": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Industry of the person themselves; include/exclude entries whose `value` is one of the 147 `industry` values from GET /prospects/filter-options (e.g. financial services). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_title_levels": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Seniority of the current job title; entries with `value` one of exactly: cxo, vp, director, manager, senior, entry, owner, partner, training, unpaid (the `job_title_levels` list in GET /prospects/filter-options). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_title_role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Department of the current job title; entries with `value` one of the 24 `job_title_role` values in GET /prospects/filter-options (e.g. engineering, sales, finance) — `jobTitleRoleToSubRole` in the same response lists each role's sub-roles. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_title_sub_role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Sub-department of the current job title; entries with `value` one of the 106 `job_title_sub_role` values in GET /prospects/filter-options (e.g. software, account_executive, data_science). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_size": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Headcount bracket of the current employer; entries with `value` one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+ — brackets only, so use `rangeInputs.job_company_employee_count` for an arbitrary headcount range. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_inferred_revenue": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Inferred annual revenue bracket of the current employer; entries with `value` one of exactly: $0-$1m, $1m-$10m, $10m-$25m, $25m-$50m, $50m-$100m, $100m-$250m, $250m-$500m, $500m-$1b, $1b-$10b, $10b+ (matched case-insensitively, so $1M-$10M also works). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_industry": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Industry of the current employer; entries with `value` one of the same 147 industry values, listed under `job_company_industry` in GET /prospects/filter-options. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_location_country": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Country of the current employer's headquarters; entries with a lower-case `value` from the 249 `job_company_location_country` values in GET /prospects/filter-options (e.g. united states, germany) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_location_region": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Region or state of the current employer's headquarters; entries with a free-text lower-case `value` such as california — resolve names with GET /prospects/autocomplete?field=region."
                      },
                      "job_company_location_continent": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Continent of the current employer's headquarters; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.location.continent": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Continent of the headquarters of any PAST employer; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.title.levels": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Seniority of any past job title; entries with `value` one of exactly: cxo, vp, director, manager, senior, entry, owner, partner, training, unpaid. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.title.role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Department of any past job title; entries with `value` one of the 24 `experience.title.role` values in GET /prospects/filter-options — the same list as `job_title_role`. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.title.sub_role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Sub-department of any past job title; entries with `value` one of the 106 `experience.title.sub_role` values in GET /prospects/filter-options — the same list as `job_title_sub_role`. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.location.country": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Country of the headquarters of any past employer; entries with a lower-case `value` from the 249 `experience.company.location.country` values in GET /prospects/filter-options (e.g. united states) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.industry": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Industry of any past employer; entries with `value` one of the same 147 industry values, listed under `experience.company.industry` in GET /prospects/filter-options. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "languages.name": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Languages the person lists; entries with a lower-case `value` from the 526 `languages.name` values in GET /prospects/filter-options (e.g. english, german) — language NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "location_continent": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Continent the person lives in; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "location_country": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Country the person lives in; entries with a lower-case `value` from the 249 `location_country` values in GET /prospects/filter-options (e.g. united states, united kingdom) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "location_region": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Region or state the person lives in; entries with a free-text lower-case `value` such as california — resolve names with GET /prospects/autocomplete?field=region."
                      },
                      "education.degrees": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Degrees held; entries with `value` one of the 171 `education.degrees` values in GET /prospects/filter-options (e.g. bachelors, masters, master of business administration). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.type": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Type of any past employer; entries with `value` one of exactly: educational, government, nonprofit, private, public, public_subsidiary. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_name": {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 500
                          },
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "maxLength": 500
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "status": {
                                      "type": "string",
                                      "enum": [
                                        "include",
                                        "exclude"
                                      ],
                                      "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                    },
                                    "value": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                    },
                                    "label": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                    }
                                  },
                                  "required": [
                                    "status",
                                    "value"
                                  ]
                                }
                              ]
                            },
                            "maxItems": 1000
                          }
                        ],
                        "description": "Name of the current employer, lower-case (e.g. stripe); include/exclude entries, a bare string, or an array of strings (bare strings are includes) — resolve names with GET /prospects/autocomplete?field=company."
                      },
                      "job_company_website": {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 500
                          },
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "maxLength": 500
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "status": {
                                      "type": "string",
                                      "enum": [
                                        "include",
                                        "exclude"
                                      ],
                                      "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                    },
                                    "value": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                    },
                                    "label": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                    }
                                  },
                                  "required": [
                                    "status",
                                    "value"
                                  ]
                                }
                              ]
                            },
                            "maxItems": 1000
                          }
                        ],
                        "description": "Website domain of the current employer (e.g. stripe.com — scheme, www and trailing slash are stripped); same value shapes as `job_company_name`; resolve with GET /prospects/autocomplete?field=website."
                      },
                      "full_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, but matched as an EXACT lower-case term against the stored full name (e.g. ada nwosu): there is no partial matching, so a differently cased or partial name is accepted and silently matches nothing. A string, or an array of names that are OR-joined (the provider caps a terms list at 1000)."
                      },
                      "first_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term: a different case or a nickname is accepted and silently matches nothing. A string, or an array of names that are OR-joined. Cannot be stored in a saved search (422 SAVED_SEARCH_FILTERS_UNSUPPORTED)."
                      },
                      "last_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term: a different case or spelling is accepted and silently matches nothing. A string, or an array of names that are OR-joined. Cannot be stored in a saved search (422 SAVED_SEARCH_FILTERS_UNSUPPORTED)."
                      },
                      "sex": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "One of exactly: female, male. A string, or an array of both (OR-joined)."
                      },
                      "work_email": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term against the stored work email: a different case or an alias is accepted and silently matches nothing. A string, or an array of addresses that are OR-joined."
                      },
                      "mobile_phone": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term, so send E.164 with the leading + (e.g. +14155552671); any other formatting is accepted and silently matches nothing. A string, or an array of numbers that are OR-joined."
                      },
                      "personal_emails": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term against every personal email on the profile: any other spelling is accepted and silently matches nothing. A string, or an array of addresses that are OR-joined."
                      },
                      "job_title": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Exact lower-case current job title (e.g. chief financial officer); a string or an array of titles — use `keywords` for partial matches and GET /prospects/autocomplete?field=title for suggestions."
                      },
                      "job_company_location_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Locality of the current employer's headquarters as a PDL location name (e.g. san francisco, california, united states); resolve with GET /prospects/autocomplete?field=location."
                      },
                      "location_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Where the person lives, as a PDL location name (e.g. london, greater london, united kingdom); resolve with GET /prospects/autocomplete?field=location."
                      },
                      "linkedin_url": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term in the stored form linkedin.com/in/<slug> — no scheme, no www., no trailing slash; anything else is accepted and silently matches nothing. Prefer the top-level `linkedinUrl`, which IS normalised before matching. A string, or an array of URLs that are OR-joined."
                      },
                      "github_url": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term in the stored form github.com/<username> — no scheme, no trailing slash; anything else is accepted and silently matches nothing. A string, or an array of URLs that are OR-joined."
                      },
                      "github_username": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term against the stored GitHub username: a different case is accepted and silently matches nothing. A string, or an array of usernames that are OR-joined."
                      },
                      "facebook_url": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term in the stored form facebook.com/<slug> — no scheme, no trailing slash; anything else is accepted and silently matches nothing. A string, or an array of URLs that are OR-joined."
                      },
                      "education.school.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case name of a school attended (e.g. stanford university); resolve with GET /prospects/autocomplete?field=school."
                      },
                      "experience.title.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Exact lower-case title held at any past job; a string or an array of titles."
                      },
                      "experience.company.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case name of any past employer; a string or an array — resolve with GET /prospects/autocomplete?field=company."
                      },
                      "experience.company.website": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text: the website host of any past employer (e.g. stripe.com). The scheme, www. and a trailing slash are stripped and both the host+path and host-only forms are tried, so a full URL still matches; a host the provider does not store matches nothing. A string, or an array of hosts that are OR-joined."
                      },
                      "job_start_date": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term and NOT as a range: the stored start date of the current job, YYYY-MM or YYYY-MM-DD exactly as stored (most profiles store YYYY-MM), so 2023-05-01 does not match a profile stored as 2023-05. A string, or an array of dates that are OR-joined."
                      },
                      "skills": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case skill (e.g. python); a string, or an array of skills any of which may match — resolve with GET /prospects/autocomplete?field=skill."
                      },
                      "certifications.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case certification name (e.g. pmp); a string or an array."
                      },
                      "experience.company.location.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Locality of any past employer's headquarters as a PDL location name."
                      },
                      "keywords": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "maxItems": 25,
                        "description": "Free text: up to 25 terms (200 chars each), each matched against the current job title only and OR-joined, so any one may match. A bare term matches anywhere in the title (growth matches Head of Growth); a term carrying your own * or ? must match the WHOLE title (manager* starts with, *manager ends with, ? is exactly one character). Matching is case-insensitive. A term with no text other than wildcards is ignored, since it would match every title, and a list holding only such terms does not count as search criteria. This is the costliest filter the provider serves, so keep the list short."
                      },
                      "excludedKeywords": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "maxItems": 25,
                        "description": "Free text: up to 25 terms (200 chars each) using exactly the same matching rules as `keywords`, but REMOVING every prospect whose current job title matches any one of them — keywords [engineer] with excludedKeywords [infrastructure] keeps Engineer VP and drops Engineer VP Infrastructure. It reads the whole job title, so it also removes rows matched by `job_title`. A term with no text other than wildcards is ignored, since it would remove every prospect that has a job title. Exclusions only narrow a result set: on their own they are not search criteria and a request carrying nothing else is rejected."
                      },
                      "rangeInputs": {
                        "type": "object",
                        "properties": {
                          "job_company_employee_count": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Inclusive lower bound (0 is treated as no bound)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Headcount of the current employer; accepted values are whole numbers and both bounds are inclusive. A min of 0 is ignored rather than applied, so cap headcount with max alone."
                          },
                          "inferred_years_experience": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Inclusive lower bound (0 is treated as no bound)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Total years of professional experience; accepted values are whole numbers of years and both bounds are inclusive. A min of 0 is ignored rather than applied."
                          },
                          "job_company_total_funding_raised": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Inclusive lower bound (0 is treated as no bound)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Total funding raised by the current employer; accepted values are whole US dollars, not millions (10000000 means $10M), and both bounds are inclusive. A min of 0 is ignored rather than applied."
                          }
                        },
                        "description": "Numeric range filters, each key one of exactly: `job_company_employee_count`, `inferred_years_experience`, `job_company_total_funding_raised` (any other key is rejected). Each value is `{ min?, max? }` with at least one bound and min <= max; several ranges AND with each other and with every other filter."
                      }
                    },
                    "description": "Literal filters, one of the four filter sources. People filters in the search vocabulary: include/exclude fields take `[{ status, value }]` entries, term fields a string or an array of strings, `rangeInputs` `{ min, max }` ranges — every field and its accepted values are listed by GET /prospects/filter-options. On this endpoint a value outside a field's listed vocabulary is refused with 422 VALIDATION_FAILED, naming the field and the value, before anything is billed."
                  },
                  "savedSearchId": {
                    "type": "string",
                    "description": "Id of one of your PEOPLE saved searches to take the filters from instead of `filters` (a company saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH)."
                  },
                  "savedSearchName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Exact title of one of your people saved searches to take the filters from instead of `filters`; two searches sharing the title answer 409 SAVED_SEARCH_NAME_AMBIGUOUS."
                  },
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Natural-language description of who to find (max 2000 chars), converted into filters server-side instead of `filters`; criteria that could not be mapped come back as `unresolvedCriteria`, and a query yielding no filter answers 422 QUERY_FILTERS_INVALID."
                  },
                  "size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 10,
                    "description": "Profiles per page (1-100, default 10); the search pre-checks 2 credits per requested profile and debits 2 credits per profile returned."
                  },
                  "scrollToken": {
                    "type": "string",
                    "description": "The `scrollToken` returned by the previous page, sent together with the same filter source, to fetch the next page."
                  },
                  "linkedinUrl": {
                    "type": "string",
                    "description": "A LinkedIn profile URL to look up one person (normalised before matching); counts as search criteria on its own."
                  }
                },
                "description": "Exactly one filter source — `filters`, `savedSearchId`, `savedSearchName` or `query` — plus optional paging. With `filters`, at least one non-empty filter value, a `linkedinUrl` or a `scrollToken` is required, and enum-backed values must come from GET /prospects/filter-options (422 otherwise, before anything is billed)."
              }
            }
          }
        }
      }
    },
    "/business/prospects/search/save-to-list": {
      "post": {
        "operationId": "saveProspectSearchToList",
        "summary": "Save people-search results into a list",
        "tags": [
          "Prospect search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "listIds",
                    "enrich"
                  ],
                  "properties": {
                    "listIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Destination list ids the save is writing into (the reused list, or the one just created)."
                    },
                    "enrich": {
                      "type": "string",
                      "enum": [
                        "none",
                        "email",
                        "phone",
                        "phone_and_email"
                      ],
                      "description": "Echo of the enrichment mode the job is running."
                    },
                    "totalContacts": {
                      "type": "integer",
                      "description": "Enrichment modes only: how many rows the job will process."
                    },
                    "estimatedMinutes": {
                      "type": "integer",
                      "description": "Enrichment modes only: rough completion estimate."
                    },
                    "jobId": {
                      "type": "string",
                      "description": "Enrichment modes only: the run's job, to poll at GET /business/jobs/{jobId}."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "processing"
                      ],
                      "description": "Enrichment modes only: pending while the job waits behind your other enrichment job, processing once it runs."
                    },
                    "campaign": {
                      "type": "object",
                      "required": [
                        "id",
                        "attached"
                      ],
                      "description": "Only when a campaign was requested.",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "attached": {
                          "type": "boolean",
                          "description": "False when the attach failed after the save had already started; the save still runs."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "listIds": [
                    "6a8da255c5017e82fb66df5d"
                  ],
                  "enrich": "phone_and_email",
                  "totalContacts": 500,
                  "estimatedMinutes": 25,
                  "jobId": "68a2109c9c41d20014b41003",
                  "status": "pending",
                  "campaign": {
                    "id": "6a8da7718707dbcfb4448b96",
                    "attached": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Run the search server-side and save up to `limit` matches into a contact list. The filter source is exactly one of `filters`, a saved search (`savedSearchId` / `savedSearchName`), or a natural-language `query` — the same contract as POST /prospects/search. The destination is exactly one of `listId` or `listName`; `listName` is create-or-reuse by exact name (case-insensitive), a name shared by two lists is a 409, and system list names are refused.\n\n`enrich` selects what runs on the saved rows: `none` (default) saves the search rows as-is at 2 credits per row; `email`, `phone` or `phone_and_email` run the enrichment waterfall while saving (50 / 200 / 250 credits per row pre-checked), and rows already carrying the requested data are not re-charged. Only the enrichment modes report `totalContacts`, `estimatedMinutes`, and the run's `jobId` and `status` (`pending` while it waits behind your other enrichment job, `processing` once it runs): poll `GET /business/jobs/{jobId}` for its status and counts. A run whose balance runs out mid-run pauses (`stopped`) and is resumed from the app.\n\nAn optional `campaignId` XOR `campaignName` attaches the destination list to that campaign in the same motion, and the response's `campaign.attached` says whether that succeeded — a failed attach never retracts a started save. The attach happens when the save STARTS: a draft campaign enrols the full list at approval, while an ACTIVE non-dynamic campaign enrols only the rows present at attach time.\n\nAlways async: 202 means the job started, not that the list is populated — poll the list's rows. Billing: this runs its own search, it does NOT reuse a prior POST /prospects/search, so previewing first and then saving pays for the search twice. Saving a hand-picked subset of results is not supported; narrow the filters instead.\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — The balance does not cover the pre-check for this request; nothing was billed.\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id or exact title.\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign of yours matches `campaignId` / `campaignName`; nothing was saved.\n- `404` `LIST_NOT_FOUND` — With `enrich` other than `none`: `listId` is not one of your lists, or it was deleted before the save started. Nothing was saved or billed.\n- `409` `SAVED_SEARCH_NAME_AMBIGUOUS` — Two of your saved searches share that title — reference it by `savedSearchId` instead.\n- `409` `CAMPAIGN_NAME_AMBIGUOUS` — Two of your campaigns share that name — pass `campaignId` instead.\n- `409` `LIST_NAME_AMBIGUOUS` — Two of your lists share that name — pass `listId` instead.\n- `409` `LIST_NAME_TAKEN` — With `enrich` other than `none`: the new list for `listName` could not be created because the name was taken in the meantime. Retry, or pass `listId`. Nothing was saved or billed.\n- `409` `ALL_CONTACTS_ALREADY_ENRICHED` — Every matching row already carries the requested enrichment — nothing to run and nothing billed.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `422` `SAVED_SEARCH_TYPE_MISMATCH` — The saved search exists but stores the other kind of filters; `param` is `savedSearchId`.\n- `422` `SAVED_SEARCH_INVALID` — The STORED filters no longer form a runnable search — every value was retired, or the blob translates to nothing.\n- `422` `QUERY_FILTERS_INVALID` — The natural-language `query` produced no usable filter; name concrete criteria.\n- `422` `LIST_NAME_RESERVED` — `listName` is a system/dynamic list title and cannot be a destination.\n- `422` `CAMPAIGN_LIST_CAP_REACHED` — The campaign already holds the maximum number of attached lists; nothing was saved.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "properties": {
                      "industry": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Industry of the person themselves; include/exclude entries whose `value` is one of the 147 `industry` values from GET /prospects/filter-options (e.g. financial services). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_title_levels": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Seniority of the current job title; entries with `value` one of exactly: cxo, vp, director, manager, senior, entry, owner, partner, training, unpaid (the `job_title_levels` list in GET /prospects/filter-options). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_title_role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Department of the current job title; entries with `value` one of the 24 `job_title_role` values in GET /prospects/filter-options (e.g. engineering, sales, finance) — `jobTitleRoleToSubRole` in the same response lists each role's sub-roles. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_title_sub_role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Sub-department of the current job title; entries with `value` one of the 106 `job_title_sub_role` values in GET /prospects/filter-options (e.g. software, account_executive, data_science). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_size": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Headcount bracket of the current employer; entries with `value` one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+ — brackets only, so use `rangeInputs.job_company_employee_count` for an arbitrary headcount range. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_inferred_revenue": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Inferred annual revenue bracket of the current employer; entries with `value` one of exactly: $0-$1m, $1m-$10m, $10m-$25m, $25m-$50m, $50m-$100m, $100m-$250m, $250m-$500m, $500m-$1b, $1b-$10b, $10b+ (matched case-insensitively, so $1M-$10M also works). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_industry": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Industry of the current employer; entries with `value` one of the same 147 industry values, listed under `job_company_industry` in GET /prospects/filter-options. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_location_country": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Country of the current employer's headquarters; entries with a lower-case `value` from the 249 `job_company_location_country` values in GET /prospects/filter-options (e.g. united states, germany) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_location_region": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Region or state of the current employer's headquarters; entries with a free-text lower-case `value` such as california — resolve names with GET /prospects/autocomplete?field=region."
                      },
                      "job_company_location_continent": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Continent of the current employer's headquarters; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.location.continent": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Continent of the headquarters of any PAST employer; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.title.levels": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Seniority of any past job title; entries with `value` one of exactly: cxo, vp, director, manager, senior, entry, owner, partner, training, unpaid. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.title.role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Department of any past job title; entries with `value` one of the 24 `experience.title.role` values in GET /prospects/filter-options — the same list as `job_title_role`. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.title.sub_role": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Sub-department of any past job title; entries with `value` one of the 106 `experience.title.sub_role` values in GET /prospects/filter-options — the same list as `job_title_sub_role`. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.location.country": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Country of the headquarters of any past employer; entries with a lower-case `value` from the 249 `experience.company.location.country` values in GET /prospects/filter-options (e.g. united states) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.industry": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Industry of any past employer; entries with `value` one of the same 147 industry values, listed under `experience.company.industry` in GET /prospects/filter-options. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "languages.name": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Languages the person lists; entries with a lower-case `value` from the 526 `languages.name` values in GET /prospects/filter-options (e.g. english, german) — language NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "location_continent": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Continent the person lives in; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "location_country": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Country the person lives in; entries with a lower-case `value` from the 249 `location_country` values in GET /prospects/filter-options (e.g. united states, united kingdom) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "location_region": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Region or state the person lives in; entries with a free-text lower-case `value` such as california — resolve names with GET /prospects/autocomplete?field=region."
                      },
                      "education.degrees": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Degrees held; entries with `value` one of the 171 `education.degrees` values in GET /prospects/filter-options (e.g. bachelors, masters, master of business administration). Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "experience.company.type": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                            },
                            "value": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                            },
                            "label": {
                              "type": "string",
                              "maxLength": 500,
                              "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                            }
                          },
                          "required": [
                            "status",
                            "value"
                          ]
                        },
                        "maxItems": 1000,
                        "description": "Type of any past employer; entries with `value` one of exactly: educational, government, nonprofit, private, public, public_subsidiary. Include values are OR-joined and every exclude applies; at most 1000 entries."
                      },
                      "job_company_name": {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 500
                          },
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "maxLength": 500
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "status": {
                                      "type": "string",
                                      "enum": [
                                        "include",
                                        "exclude"
                                      ],
                                      "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                    },
                                    "value": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                    },
                                    "label": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                    }
                                  },
                                  "required": [
                                    "status",
                                    "value"
                                  ]
                                }
                              ]
                            },
                            "maxItems": 1000
                          }
                        ],
                        "description": "Name of the current employer, lower-case (e.g. stripe); include/exclude entries, a bare string, or an array of strings (bare strings are includes) — resolve names with GET /prospects/autocomplete?field=company."
                      },
                      "job_company_website": {
                        "anyOf": [
                          {
                            "type": "string",
                            "maxLength": 500
                          },
                          {
                            "type": "array",
                            "items": {
                              "anyOf": [
                                {
                                  "type": "string",
                                  "maxLength": 500
                                },
                                {
                                  "type": "object",
                                  "properties": {
                                    "status": {
                                      "type": "string",
                                      "enum": [
                                        "include",
                                        "exclude"
                                      ],
                                      "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                    },
                                    "value": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                    },
                                    "label": {
                                      "type": "string",
                                      "maxLength": 500,
                                      "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                    }
                                  },
                                  "required": [
                                    "status",
                                    "value"
                                  ]
                                }
                              ]
                            },
                            "maxItems": 1000
                          }
                        ],
                        "description": "Website domain of the current employer (e.g. stripe.com — scheme, www and trailing slash are stripped); same value shapes as `job_company_name`; resolve with GET /prospects/autocomplete?field=website."
                      },
                      "full_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, but matched as an EXACT lower-case term against the stored full name (e.g. ada nwosu): there is no partial matching, so a differently cased or partial name is accepted and silently matches nothing. A string, or an array of names that are OR-joined (the provider caps a terms list at 1000)."
                      },
                      "first_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term: a different case or a nickname is accepted and silently matches nothing. A string, or an array of names that are OR-joined. Cannot be stored in a saved search (422 SAVED_SEARCH_FILTERS_UNSUPPORTED)."
                      },
                      "last_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term: a different case or spelling is accepted and silently matches nothing. A string, or an array of names that are OR-joined. Cannot be stored in a saved search (422 SAVED_SEARCH_FILTERS_UNSUPPORTED)."
                      },
                      "sex": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "One of exactly: female, male. A string, or an array of both (OR-joined)."
                      },
                      "work_email": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term against the stored work email: a different case or an alias is accepted and silently matches nothing. A string, or an array of addresses that are OR-joined."
                      },
                      "mobile_phone": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term, so send E.164 with the leading + (e.g. +14155552671); any other formatting is accepted and silently matches nothing. A string, or an array of numbers that are OR-joined."
                      },
                      "personal_emails": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term against every personal email on the profile: any other spelling is accepted and silently matches nothing. A string, or an array of addresses that are OR-joined."
                      },
                      "job_title": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Exact lower-case current job title (e.g. chief financial officer); a string or an array of titles — use `keywords` for partial matches and GET /prospects/autocomplete?field=title for suggestions."
                      },
                      "job_company_location_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Locality of the current employer's headquarters as a PDL location name (e.g. san francisco, california, united states); resolve with GET /prospects/autocomplete?field=location."
                      },
                      "location_name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Where the person lives, as a PDL location name (e.g. london, greater london, united kingdom); resolve with GET /prospects/autocomplete?field=location."
                      },
                      "linkedin_url": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term in the stored form linkedin.com/in/<slug> — no scheme, no www., no trailing slash; anything else is accepted and silently matches nothing. Prefer the top-level `linkedinUrl`, which IS normalised before matching. A string, or an array of URLs that are OR-joined."
                      },
                      "github_url": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term in the stored form github.com/<username> — no scheme, no trailing slash; anything else is accepted and silently matches nothing. A string, or an array of URLs that are OR-joined."
                      },
                      "github_username": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT lower-case term against the stored GitHub username: a different case is accepted and silently matches nothing. A string, or an array of usernames that are OR-joined."
                      },
                      "facebook_url": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term in the stored form facebook.com/<slug> — no scheme, no trailing slash; anything else is accepted and silently matches nothing. A string, or an array of URLs that are OR-joined."
                      },
                      "education.school.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case name of a school attended (e.g. stanford university); resolve with GET /prospects/autocomplete?field=school."
                      },
                      "experience.title.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Exact lower-case title held at any past job; a string or an array of titles."
                      },
                      "experience.company.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case name of any past employer; a string or an array — resolve with GET /prospects/autocomplete?field=company."
                      },
                      "experience.company.website": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text: the website host of any past employer (e.g. stripe.com). The scheme, www. and a trailing slash are stripped and both the host+path and host-only forms are tried, so a full URL still matches; a host the provider does not store matches nothing. A string, or an array of hosts that are OR-joined."
                      },
                      "job_start_date": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Free text, matched as an EXACT term and NOT as a range: the stored start date of the current job, YYYY-MM or YYYY-MM-DD exactly as stored (most profiles store YYYY-MM), so 2023-05-01 does not match a profile stored as 2023-05. A string, or an array of dates that are OR-joined."
                      },
                      "skills": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case skill (e.g. python); a string, or an array of skills any of which may match — resolve with GET /prospects/autocomplete?field=skill."
                      },
                      "certifications.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Lower-case certification name (e.g. pmp); a string or an array."
                      },
                      "experience.company.location.name": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          },
                          {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          }
                        ],
                        "description": "Locality of any past employer's headquarters as a PDL location name."
                      },
                      "keywords": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "maxItems": 25,
                        "description": "Free text: up to 25 terms (200 chars each), each matched against the current job title only and OR-joined, so any one may match. A bare term matches anywhere in the title (growth matches Head of Growth); a term carrying your own * or ? must match the WHOLE title (manager* starts with, *manager ends with, ? is exactly one character). Matching is case-insensitive. A term with no text other than wildcards is ignored, since it would match every title, and a list holding only such terms does not count as search criteria. This is the costliest filter the provider serves, so keep the list short."
                      },
                      "excludedKeywords": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "maxItems": 25,
                        "description": "Free text: up to 25 terms (200 chars each) using exactly the same matching rules as `keywords`, but REMOVING every prospect whose current job title matches any one of them — keywords [engineer] with excludedKeywords [infrastructure] keeps Engineer VP and drops Engineer VP Infrastructure. It reads the whole job title, so it also removes rows matched by `job_title`. A term with no text other than wildcards is ignored, since it would remove every prospect that has a job title. Exclusions only narrow a result set: on their own they are not search criteria and a request carrying nothing else is rejected."
                      },
                      "rangeInputs": {
                        "type": "object",
                        "properties": {
                          "job_company_employee_count": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Inclusive lower bound (0 is treated as no bound)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Headcount of the current employer; accepted values are whole numbers and both bounds are inclusive. A min of 0 is ignored rather than applied, so cap headcount with max alone."
                          },
                          "inferred_years_experience": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Inclusive lower bound (0 is treated as no bound)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Total years of professional experience; accepted values are whole numbers of years and both bounds are inclusive. A min of 0 is ignored rather than applied."
                          },
                          "job_company_total_funding_raised": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Inclusive lower bound (0 is treated as no bound)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Total funding raised by the current employer; accepted values are whole US dollars, not millions (10000000 means $10M), and both bounds are inclusive. A min of 0 is ignored rather than applied."
                          }
                        },
                        "description": "Numeric range filters, each key one of exactly: `job_company_employee_count`, `inferred_years_experience`, `job_company_total_funding_raised` (any other key is rejected). Each value is `{ min?, max? }` with at least one bound and min <= max; several ranges AND with each other and with every other filter."
                      }
                    },
                    "description": "Literal filters, one of the four filter sources — the same vocabulary as POST /prospects/search. People filters in the search vocabulary: include/exclude fields take `[{ status, value }]` entries, term fields a string or an array of strings, `rangeInputs` `{ min, max }` ranges — every field and its accepted values are listed by GET /prospects/filter-options. On this endpoint a value outside a field's listed vocabulary is refused with 422 VALIDATION_FAILED, naming the field and the value, before anything is billed. Must contain at least one non-empty value."
                  },
                  "savedSearchId": {
                    "type": "string",
                    "description": "Id of one of your PEOPLE saved searches to take the filters from instead of `filters` (a company saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH)."
                  },
                  "savedSearchName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Exact title of one of your people saved searches to take the filters from instead of `filters`; two searches sharing the title answer 409 SAVED_SEARCH_NAME_AMBIGUOUS."
                  },
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Natural-language description of who to find (max 2000 chars), converted into filters server-side instead of `filters`; criteria that could not be mapped come back as `unresolvedCriteria`, and a query yielding no filter answers 422 QUERY_FILTERS_INVALID."
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum number of matching profiles to save (1-10000). Credits are pre-checked per row before the job starts: 2 with `enrich: none`, otherwise the enrichment price per row (402 INSUFFICIENT_CREDITS when the balance is short)."
                  },
                  "listId": {
                    "type": "string",
                    "description": "Id of an existing contact list to save into (exactly one of `listId` / `listName`)."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Name of the destination contact list, created when none exists; an existing list with the same name (case-insensitive) is reused, a name shared by several lists answers 409 LIST_NAME_AMBIGUOUS, and system list names answer 422 LIST_NAME_RESERVED."
                  },
                  "enrich": {
                    "type": "string",
                    "enum": [
                      "none",
                      "email",
                      "phone",
                      "phone_and_email"
                    ],
                    "default": "none",
                    "description": "What to run on the saved rows: `none` (default) saves the search rows as-is for 2 credits per row; `email` (pre-checks 50 credits per row), `phone` (200) or `phone_and_email` (250) run the enrichment waterfall while saving — rows already carrying the requested data are not re-charged."
                  },
                  "campaignId": {
                    "type": "string",
                    "description": "Id of one of your campaigns to attach the destination list to once the save has started (optional; exactly one of `campaignId` / `campaignName`)."
                  },
                  "campaignName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Exact name of one of your campaigns to attach the destination list to (optional); no match answers 404 CAMPAIGN_NOT_FOUND and a shared name 409 CAMPAIGN_NAME_AMBIGUOUS."
                  }
                },
                "required": [
                  "limit"
                ],
                "description": "Exactly one filter source (`filters` | `savedSearchId` | `savedSearchName` | `query`), exactly one destination (`listId` | `listName`), an optional campaign (`campaignId` | `campaignName`, never both), plus `limit` and `enrich`."
              }
            }
          }
        }
      }
    },
    "/business/campaigns/{campaignId}/stop": {
      "post": {
        "operationId": "stopCampaign",
        "summary": "Stop an active campaign (approve re-activates it)",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaign": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "stopped"
                          ],
                          "description": "A stopped campaign always lands in this status."
                        }
                      },
                      "required": [
                        "id",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "campaign"
                  ]
                },
                "example": {
                  "campaign": {
                    "id": "6a8dce146dc0b3d9029c22d0",
                    "status": "stopped"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Stops the campaign: sending halts immediately and its open task mirrors are cleared, while each contact keeps its own state so POST /business/campaigns/{campaignId}/approve resumes the same campaign rather than re-initializing it. Stopping a draft is allowed and simply parks it in `stopped`. Only the token owner's own campaigns can be stopped: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: this endpoint and DELETE /business/campaigns/{campaignId} share a tighter cap of 10 requests/minute and 100/day, applied inside the shared campaigns bucket of 30 requests/minute and 1,000/day per token owner (shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint).\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `409` `CAMPAIGN_BUSY` — Another approve or stop is holding this campaign's activation lock. Retry in a few seconds.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Either this endpoint's own cap (10 requests/minute, 100/day) or the shared campaigns bucket (30/minute, 1,000/day for this token owner, shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call) was exceeded. The RateLimit-* headers on the response describe the shared bucket, so a refusal from this endpoint's own cap can still report requests remaining and carries no Retry-After.\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/duplicate": {
      "post": {
        "operationId": "duplicateCampaign",
        "summary": "Copy a campaign as a fresh draft",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "campaign": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Id of the new copy."
                        },
                        "name": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Name of the new copy."
                        }
                      },
                      "required": [
                        "id",
                        "name"
                      ]
                    }
                  },
                  "required": [
                    "campaign"
                  ]
                },
                "example": {
                  "campaign": {
                    "id": "6a8dce4da4566f4f2454bd07",
                    "name": "Copy of Q3 fintech outreach"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Copies the campaign into a new draft named \"Copy of <name>\". The copy carries the same sequence steps, schedule settings and source lists, and starts in `initializing` with no enrolled contacts, no analytics and no queued sends. Nothing is sent until you approve the copy. Only the token owner's own campaigns can be duplicated: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/variables": {
      "get": {
        "operationId": "listCampaignVariables",
        "summary": "The personalization variables this campaign's steps can use",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "variables": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "token": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The literal token to paste into a step, for example {Column: Lead Score}."
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The column's name."
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The column's value type (for example text, number, enum, date)."
                          },
                          "listId": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The list that defines the column."
                          },
                          "listName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "token",
                          "name",
                          "type",
                          "listId",
                          "listName"
                        ]
                      }
                    }
                  },
                  "required": [
                    "variables"
                  ]
                },
                "example": {
                  "variables": [
                    {
                      "token": "{Column: Lead Score}",
                      "name": "Lead Score",
                      "type": "enum",
                      "listId": "6a1edba88936e0fe1b20287c",
                      "listName": "Fintech CFOs - US"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Lists the custom and smart column tokens the campaign's steps can personalise with, deduplicated across the campaign's source lists (the first list that defines a column name wins, which is how values resolve at send time). Paste a `token` verbatim into a step's subject or body and it is substituted per lead when the message is sent. Columns whose name contains a brace or a pipe are skipped because they could never form a usable token. Built-in tokens such as {Contact First Name} are always available and are not listed here. Only the token owner's own campaigns resolve, and a deleted campaign answers 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/stats": {
      "get": {
        "operationId": "getCampaignStats",
        "summary": "A campaign's headline metrics since `since`",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "ISO 8601 date-time from which the total* counters are accumulated (default: 12 months ago).",
            "schema": {
              "type": "string",
              "description": "ISO 8601 date-time from which the total* counters are accumulated (default: 12 months ago)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stats": {
                      "type": "object",
                      "properties": {
                        "totalSent": {
                          "type": "integer",
                          "description": "Messages sent since `since`."
                        },
                        "totalOpened": {
                          "type": "integer",
                          "description": "Distinct contacts who opened since `since` (needs open tracking enabled)."
                        },
                        "totalClicked": {
                          "type": "integer",
                          "description": "Distinct contacts who clicked since `since`."
                        },
                        "totalReplied": {
                          "type": "integer"
                        }
                      },
                      "required": [
                        "totalSent",
                        "totalOpened",
                        "totalClicked",
                        "totalReplied"
                      ]
                    }
                  },
                  "required": [
                    "stats"
                  ]
                },
                "example": {
                  "stats": {
                    "totalSent": 412,
                    "totalOpened": 198,
                    "totalClicked": 37,
                    "totalReplied": 22
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Returns the campaign's headline email metrics. The `total*` counters accumulate from `since` (default: 12 months ago). `totalOpened` and `totalClicked` count distinct contacts, not events. Only the token owner's own campaigns resolve: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — `since` is not an ISO 8601 date-time, or campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/leads": {
      "get": {
        "operationId": "listCampaignLeads",
        "summary": "The campaign's leads with their per-step state",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1-100 (default 25).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "description": "Page size, 1-100 (default 25)."
            }
          },
          {
            "name": "pageNum",
            "in": "query",
            "required": false,
            "description": "1-based page number (default 1).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based page number (default 1)."
            }
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "description": "Free text matched case-insensitively against the lead's full name or their company name (1-200 characters); any string is accepted, and regex metacharacters are escaped for you, so it behaves as a literal substring match. A term that matches no lead returns an empty page, not an error.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "description": "Free text matched case-insensitively against the lead's full name or their company name (1-200 characters); any string is accepted, and regex metacharacters are escaped for you, so it behaves as a literal substring match. A term that matches no lead returns an empty page, not an error."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "leads": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The campaign-membership row's id."
                          },
                          "contactId": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The underlying contact's id."
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "email": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The contact's primary email address."
                          },
                          "linkedinUrl": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "companyName": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "companyUrl": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The lead's state in this campaign as the app displays it."
                          },
                          "outcome": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Recorded outcome for the lead, when one was set."
                          },
                          "sentSteps": {
                            "type": "integer"
                          },
                          "totalSteps": {
                            "type": "integer"
                          },
                          "openCount": {
                            "type": "integer"
                          },
                          "clickCount": {
                            "type": "integer"
                          },
                          "hasOpened": {
                            "type": "boolean"
                          },
                          "hasClicked": {
                            "type": "boolean"
                          },
                          "hasReplied": {
                            "type": "boolean"
                          },
                          "hasConnected": {
                            "type": "boolean",
                            "description": "Whether a LinkedIn connection request to this lead was accepted."
                          },
                          "firstMessageReceivedAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "When the lead's first reply arrived."
                          },
                          "firstSentBy": {
                            "type": "object",
                            "properties": {
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "email": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "channel": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "name",
                              "email",
                              "channel"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "contactId",
                          "name",
                          "email",
                          "linkedinUrl",
                          "companyName",
                          "companyUrl",
                          "status",
                          "outcome",
                          "sentSteps",
                          "totalSteps",
                          "openCount",
                          "clickCount",
                          "hasOpened",
                          "hasClicked",
                          "hasReplied",
                          "hasConnected",
                          "firstMessageReceivedAt",
                          "firstSentBy"
                        ]
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "description": "1-based page number this response covers."
                        },
                        "pageSize": {
                          "type": "integer",
                          "description": "Rows requested per page."
                        },
                        "total": {
                          "type": "integer",
                          "description": "Total rows matching the query."
                        },
                        "totalPages": {
                          "type": "integer",
                          "description": "Total pages at this page size."
                        }
                      },
                      "required": [
                        "page",
                        "pageSize",
                        "total",
                        "totalPages"
                      ]
                    }
                  },
                  "required": [
                    "leads",
                    "pagination"
                  ]
                },
                "example": {
                  "leads": [
                    {
                      "id": "6a8da79aafc401ca94530c9d",
                      "contactId": "6777d930c5c5e1865dc3f562",
                      "name": "Imogen Low",
                      "email": "imogen@brightpay.com",
                      "linkedinUrl": "linkedin.com/in/imogen-low",
                      "companyName": "BrightPay",
                      "companyUrl": "brightpay.com",
                      "status": "stopped",
                      "outcome": null,
                      "sentSteps": 1,
                      "totalSteps": 2,
                      "openCount": 2,
                      "clickCount": 0,
                      "hasOpened": true,
                      "hasClicked": false,
                      "hasReplied": true,
                      "hasConnected": false,
                      "firstMessageReceivedAt": "2026-08-25T15:04:11.000Z",
                      "firstSentBy": {
                        "name": "Sam Rivera",
                        "email": "sam@yourcompany.com",
                        "channel": "email"
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "pageSize": 25,
                    "total": 9,
                    "totalPages": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Lists the contacts enrolled in the campaign with their progress through the sequence. `id` is the campaign-membership row and `contactId` is the underlying contact, so you can cross-reference the contacts API. `status` is the state the app shows for the lead (it reads `stopped` or `completed` once the campaign itself stops), `sentSteps`/`totalSteps` show progress, and `firstSentBy` names the account and channel that first reached the lead. Only the token owner's own campaigns resolve: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — A query parameter is out of range, or campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/leads/export": {
      "post": {
        "operationId": "exportCampaignLeads",
        "summary": "Export the campaign's leads to CSV",
        "tags": [
          "Campaigns"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "csv": {
                      "type": "string",
                      "description": "The whole CSV document, header row first. Empty string if the inner export produced no document."
                    }
                  },
                  "required": [
                    "csv"
                  ]
                },
                "example": {
                  "csv": "First Name,Last Name,Email,Company,Status,Steps Sent\nImogen,Low,imogen@brightpay.com,BrightPay,stopped,1\nAkshat,Jain,akshat@brightpay.com,BrightPay,stopped,0\n"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Exports every lead in the campaign as a CSV document returned inline in the JSON body under `csv` (first row is the header). There are no filters - use GET /business/campaigns/{campaignId}/leads when you want a page or a search. Very large campaigns are refused with 422 EXPORT_LIMIT_EXCEEDED rather than truncated. Only the token owner's own campaigns can be exported: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: this endpoint has a tighter cap of 3 requests/minute and 30/day, applied inside the shared campaigns bucket of 30 requests/minute and 1,000/day per token owner (shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint).\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `NO_LEADS_TO_EXPORT` — The campaign exists but has no enrolled leads to export yet.\n- `422` `EXPORT_LIMIT_EXCEEDED` — The campaign has more leads than a single export may contain.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Either this endpoint's own cap (3 requests/minute, 30/day) or the shared campaigns bucket (30/minute, 1,000/day for this token owner, shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call) was exceeded. The RateLimit-* headers on the response describe the shared bucket, so a refusal from this endpoint's own cap can still report requests remaining and carries no Retry-After.\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/steps/{stepId}/generate": {
      "post": {
        "operationId": "generateCampaignStepPreview",
        "summary": "Render the step for a sample lead without saving or sending",
        "tags": [
          "Campaign steps"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          },
          {
            "name": "stepId",
            "in": "path",
            "required": true,
            "description": "The sequence step's id, as returned by GET /business/campaigns/{campaignId}/steps (24-character hex ObjectId).",
            "schema": {
              "type": "string",
              "description": "The sequence step's id, as returned by GET /business/campaigns/{campaignId}/steps (24-character hex ObjectId)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stepId": {
                      "type": "string",
                      "description": "The step that was rendered."
                    },
                    "preview": {
                      "type": "object",
                      "properties": {
                        "subject": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Rendered subject; null on a step with no template yet or a channel that carries none."
                        },
                        "body": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Rendered message body; null on a step with no template yet."
                        },
                        "channel": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "manual",
                            "ai_generated",
                            "ai_reply",
                            null
                          ]
                        },
                        "contact": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "name": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "email": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "jobTitle": {
                              "type": [
                                "string",
                                "null"
                              ]
                            },
                            "companyName": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          },
                          "required": [
                            "id",
                            "name",
                            "email",
                            "jobTitle",
                            "companyName"
                          ]
                        }
                      },
                      "required": [
                        "subject",
                        "body",
                        "channel",
                        "type",
                        "contact"
                      ]
                    }
                  },
                  "required": [
                    "stepId",
                    "preview"
                  ]
                },
                "example": {
                  "stepId": "6a8dce156dc0b3d9029c22d7",
                  "preview": {
                    "subject": "Quick question about BrightPay's finance hiring",
                    "body": "<p>Hi Imogen, saw BrightPay is scaling its finance team. Worth a 15-minute chat next week?</p>",
                    "channel": "email",
                    "type": "manual",
                    "contact": {
                      "id": "237d2bafce67c35eee9f011d",
                      "name": "Imogen Low",
                      "email": "imogen@brightpay.com",
                      "jobTitle": "Software Engineer",
                      "companyName": "BrightPay"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Renders this step for one sample contact from the campaign's source lists - {Variable} tokens filled and spintax resolved - and returns the result WITHOUT saving it and without sending anything. Use it to check a manual step's copy, or to see what an AI step will write. `contact` names the lead the preview was rendered against. If the campaign has no contact to render against, the answer is 422 STEP_PREVIEW_UNAVAILABLE. Only the token owner may preview. Rate limit: this endpoint has a tighter cap of 20 requests/minute and 300/day, applied inside the shared campaigns bucket of 30 requests/minute and 1,000/day per token owner (shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint).\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `404` `SEQUENCE_STEP_NOT_FOUND` — No step with this id belongs to this campaign.\n- `422` `STEP_PREVIEW_UNAVAILABLE` — There is nothing to render this step against: the campaign has no source list or no contact to sample, or generation produced no preview.\n- `422` `VALIDATION_FAILED` — campaignId or stepId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Either this endpoint's own cap (20 requests/minute, 300/day) or the shared campaigns bucket (30/minute, 1,000/day for this token owner, shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call) was exceeded. The RateLimit-* headers on the response describe the shared bucket, so a refusal from this endpoint's own cap can still report requests remaining and carries no Retry-After.\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/steps/regenerate-topics": {
      "post": {
        "operationId": "regenerateCampaignStepTopics",
        "summary": "Rebuild the AI topic plan across the campaign's steps",
        "tags": [
          "Campaign steps"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "totalStepCount": {
                      "type": "integer",
                      "description": "Sequence steps the campaign has."
                    },
                    "regeneratedStepCount": {
                      "type": "integer",
                      "description": "How many of them got a new topic; 0 when the campaign has no AI steps."
                    }
                  },
                  "required": [
                    "totalStepCount",
                    "regeneratedStepCount"
                  ]
                },
                "example": {
                  "totalStepCount": 4,
                  "regeneratedStepCount": 3
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Rebuilds the AI topic plan across the campaign's `ai_generated` steps in one pass, so the sequence reads as one narrative instead of a set of independently written steps. Manual steps are left alone, which is why `regeneratedStepCount` can be smaller than `totalStepCount`. It rewrites step topics and titles only - queued sends already created are not rewritten. Only the token owner's own campaigns can be regenerated: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: this endpoint has a tighter cap of 10 requests/minute and 100/day, applied inside the shared campaigns bucket of 30 requests/minute and 1,000/day per token owner (shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint).\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — campaignId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Either this endpoint's own cap (10 requests/minute, 100/day) or the shared campaigns bucket (30/minute, 1,000/day for this token owner, shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call) was exceeded. The RateLimit-* headers on the response describe the shared bucket, so a refusal from this endpoint's own cap can still report requests remaining and carries no Retry-After.\n- `500` `UNEXPECTED_ERROR` — Topic generation failed; the detail stays in our logs.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/campaigns/{campaignId}/scheduled-sends": {
      "get": {
        "operationId": "listScheduledSends",
        "summary": "The campaign's send queue by status",
        "tags": [
          "Scheduled sends"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignId",
            "in": "path",
            "required": true,
            "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row.",
            "schema": {
              "type": "string",
              "description": "The campaign's id (24-character hex ObjectId), as returned by POST /business/campaigns or as the campaignId of a GET /business/campaigns row."
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": true,
            "description": "Queue bucket to list: approval_required (AI-drafted sends waiting for your approval), scheduled (queued, goes out at scheduledAt), sent (delivered by Fuse or marked done), skipped (passed over, the contact moved on), stopped (declined, terminal for that contact) or overwritten (replaced by a newer row through PATCH /business/scheduled-sends/{sendId}).",
            "schema": {
              "type": "string",
              "enum": [
                "approval_required",
                "scheduled",
                "sent",
                "skipped",
                "stopped",
                "overwritten"
              ],
              "description": "Queue bucket to list: approval_required (AI-drafted sends waiting for your approval), scheduled (queued, goes out at scheduledAt), sent (delivered by Fuse or marked done), skipped (passed over, the contact moved on), stopped (declined, terminal for that contact) or overwritten (replaced by a newer row through PATCH /business/scheduled-sends/{sendId})."
            }
          },
          {
            "name": "channel",
            "in": "query",
            "required": false,
            "description": "Restrict rows to one channel, named exactly as the queue stores it (the same values a step's `channel` uses): email, linkedin_connection, linkedin_message, linkedin_visit, linkedin_like, inmail, dialer or todo. Omit to include every channel.",
            "schema": {
              "type": "string",
              "enum": [
                "email",
                "linkedin_connection",
                "linkedin_message",
                "linkedin_visit",
                "linkedin_like",
                "inmail",
                "dialer",
                "todo"
              ],
              "description": "Restrict rows to one channel, named exactly as the queue stores it (the same values a step's `channel` uses): email, linkedin_connection, linkedin_message, linkedin_visit, linkedin_like, inmail, dialer or todo. Omit to include every channel."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size, 1-100 (default 25).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "description": "Page size, 1-100 (default 25)."
            }
          },
          {
            "name": "pageNum",
            "in": "query",
            "required": false,
            "description": "1-based page number (default 1).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based page number (default 1)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "sends": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "approval_required",
                              "scheduled",
                              "sent",
                              "skipped",
                              "stopped",
                              "overwritten",
                              null
                            ]
                          },
                          "channel": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "email",
                              "linkedin_connection",
                              "linkedin_message",
                              "linkedin_visit",
                              "linkedin_like",
                              "inmail",
                              "dialer",
                              "todo",
                              null
                            ]
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "manual",
                              "ai_generated",
                              "ai_reply",
                              null
                            ],
                            "description": "How the message was produced."
                          },
                          "subject": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Null on channels that carry no subject."
                          },
                          "body": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The exact message that will be sent, including the unsubscribe footer when the campaign appends one."
                          },
                          "scheduledAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "When the send is due, in UTC."
                          },
                          "sentAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "When it went out; null until then."
                          },
                          "outcome": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "fromEmail": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Sending mailbox for email/inmail rows."
                          },
                          "fromLinkedInAccount": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Sending LinkedIn account for LinkedIn rows."
                          },
                          "cc": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "bcc": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "contact": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "email": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "linkedinUrl": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            },
                            "required": [
                              "id",
                              "name",
                              "email",
                              "linkedinUrl"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "campaignId",
                          "status",
                          "channel",
                          "type",
                          "subject",
                          "body",
                          "scheduledAt",
                          "sentAt",
                          "outcome",
                          "fromEmail",
                          "fromLinkedInAccount",
                          "cc",
                          "bcc",
                          "contact"
                        ]
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "description": "1-based page number this response covers."
                        },
                        "pageSize": {
                          "type": "integer",
                          "description": "Rows requested per page."
                        },
                        "total": {
                          "type": "integer",
                          "description": "Total rows matching the query."
                        },
                        "totalPages": {
                          "type": "integer",
                          "description": "Total pages at this page size."
                        }
                      },
                      "required": [
                        "page",
                        "pageSize",
                        "total",
                        "totalPages"
                      ]
                    }
                  },
                  "required": [
                    "sends",
                    "pagination"
                  ]
                },
                "example": {
                  "sends": [
                    {
                      "id": "6a8da7adafc401ca94530e14",
                      "campaignId": "6a8da7718707dbcfb4448b96",
                      "status": "scheduled",
                      "channel": "email",
                      "type": "manual",
                      "subject": "Quick question about BrightPay",
                      "body": "<p>Hi Imogen, saw BrightPay is scaling its finance team. Worth a 15-minute chat next week?</p>",
                      "scheduledAt": "2026-08-26T00:00:00.000Z",
                      "sentAt": null,
                      "outcome": null,
                      "fromEmail": "sam@yourcompany.com",
                      "fromLinkedInAccount": null,
                      "cc": [],
                      "bcc": [],
                      "contact": {
                        "id": "7cc23aea89efde515f9b865e",
                        "name": "Imogen Low",
                        "email": "imogen@brightpay.com",
                        "linkedinUrl": null
                      }
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "pageSize": 25,
                    "total": 8,
                    "totalPages": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Lists one bucket of the campaign's send queue. `status=approval_required` returns AI-drafted messages waiting for your decision through POST /business/scheduled-sends/approve or /decline; `scheduled` is the upcoming queue, each row due at `scheduledAt` (UTC); `sent`, `skipped`, `stopped` (declined - terminal for that contact) and `overwritten` (replaced by a newer row through PATCH /business/scheduled-sends/{sendId}) are history. `body` is the exact message that will go out, including the unsubscribe footer when the campaign appends one. Add `channel` to narrow to one channel, named exactly as a step's `channel` is. Only the token owner's own campaigns resolve: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — `status` is missing or not one of the four buckets, `channel` is not one of the stored channels, or a paging value is out of range; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/scheduled-sends/{sendId}": {
      "patch": {
        "operationId": "updateScheduledSend",
        "summary": "Edit a queued send's copy or time before it goes out",
        "tags": [
          "Scheduled sends"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sendId",
            "in": "path",
            "required": true,
            "description": "The queued send's id (the _id of a GET /business/campaigns/{campaignId}/scheduled-sends row, 24-character hex ObjectId).",
            "schema": {
              "type": "string",
              "description": "The queued send's id (the _id of a GET /business/campaigns/{campaignId}/scheduled-sends row, 24-character hex ObjectId)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "send": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Id of the NEW queued row that carries the edit; address this one from now on."
                        },
                        "replacedSendId": {
                          "type": "string",
                          "description": "The row you addressed, now marked overwritten."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "approval_required",
                            "scheduled",
                            "sent",
                            "skipped",
                            "stopped",
                            "overwritten"
                          ],
                          "description": "The queue bucket the edit stays in."
                        },
                        "subject": {
                          "type": "string",
                          "description": "The subject now on the row (the previous one when you omitted it)."
                        },
                        "scheduledAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "The send time now on the row (the previous one when you omitted it)."
                        }
                      },
                      "required": [
                        "id",
                        "replacedSendId",
                        "status",
                        "subject",
                        "scheduledAt"
                      ]
                    }
                  },
                  "required": [
                    "send"
                  ]
                },
                "example": {
                  "send": {
                    "id": "6a8dce64a4566f4f2454bd38",
                    "replacedSendId": "6a8da7adafc401ca94530e14",
                    "status": "scheduled",
                    "subject": "Quick question about BrightPay (edited)",
                    "scheduledAt": "2026-08-26T00:00:00.000Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Edits a queued send before it goes out. Send any of `subject`, `body` and `scheduledAt`; omitted fields keep the queued row's current values. IMPORTANT: the edit is not an in-place update - the row you addressed is marked `overwritten` and a NEW queued row carries the content forward, so the response returns the new `id` (and the old one as `replacedSendId`) and any further edit must address the new id. Only a send still waiting to go out can be edited: a row in `scheduled` or `approval_required`, with a send time. Anything else - sent, skipped, stopped, already overwritten, replied or failed - answers 409. Only the owner of the send's campaign may edit it. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `SCHEDULED_SEND_NOT_FOUND` — No queued send with this id exists, or it belongs to a campaign you do not own.\n- `409` `SCHEDULED_SEND_NOT_EDITABLE` — The send is no longer waiting to go out (sent, skipped, stopped, already overwritten, replied or failed), or it carries no send time.\n- `422` `VALIDATION_FAILED` — Empty body, unknown key, a subject or body over its length cap, or a scheduledAt that is not an ISO 8601 date-time; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "subject": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "Replacement subject (up to 500 characters, may be empty). Omit to keep the queued row's current subject."
                  },
                  "body": {
                    "type": "string",
                    "maxLength": 20000,
                    "description": "Replacement message body (up to 20000 characters; {Variable} tokens substitute at send time). Omit to keep the queued row's current body."
                  },
                  "scheduledAt": {
                    "type": "string",
                    "description": "New ISO 8601 send time (UTC). Omit to keep the queued row's current send time."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/business/scheduled-sends/{sendId}/skip": {
      "post": {
        "operationId": "skipScheduledSend",
        "summary": "Skip one queued send",
        "tags": [
          "Scheduled sends"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "sendId",
            "in": "path",
            "required": true,
            "description": "The queued send's id (the _id of a GET /business/campaigns/{campaignId}/scheduled-sends row, 24-character hex ObjectId).",
            "schema": {
              "type": "string",
              "description": "The queued send's id (the _id of a GET /business/campaigns/{campaignId}/scheduled-sends row, 24-character hex ObjectId)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "send": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "approval_required",
                            "scheduled",
                            "sent",
                            "skipped",
                            "stopped",
                            "overwritten"
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "send"
                  ]
                },
                "example": {
                  "send": {
                    "id": "6a8da7adafc401ca94530e14",
                    "status": "skipped"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Skips one queued send: the row is marked `skipped` and the contact's sequence ADVANCES to its next step, with the following step's wait measured from this row's scheduled time. That is what separates skip from decline, which stops the contact's sequence outright. Only a row still waiting to go out can be skipped (`scheduled`, `approval_required` or an action-required row); skipping an already skipped row succeeds again and changes nothing. Only sends belonging to campaigns you own can be skipped; anything else answers 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `SCHEDULED_SEND_NOT_FOUND` — No queued send with this id exists, or its campaign is outside your reach.\n- `409` `SCHEDULED_SEND_NOT_SKIPPABLE` — The send is already settled (sent, stopped, overwritten, replied or failed) and cannot be skipped.\n- `422` `VALIDATION_FAILED` — sendId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/scheduled-sends/approve": {
      "post": {
        "operationId": "approveScheduledSends",
        "summary": "Approve queued sends awaiting review",
        "tags": [
          "Scheduled sends"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "approved": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Ids that moved from approval_required to scheduled."
                    },
                    "ignored": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Your sends that approval cannot move in their current state."
                    },
                    "notFound": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Ids that do not exist or belong to a campaign you do not own."
                    }
                  },
                  "required": [
                    "approved",
                    "ignored",
                    "notFound"
                  ]
                },
                "example": {
                  "approved": [
                    "6a8dce70a4566f4f2454bd4f"
                  ],
                  "ignored": [
                    "6a8da7adafc401ca94530e14"
                  ],
                  "notFound": [
                    "000000000000000000000000"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Approves queued sends that are waiting for review: each row in `approval_required` moves to `scheduled` and goes out at its scheduled time. Only sends belonging to campaigns you own can be approved. The answer reports every id you passed: `approved` are the ones that moved, `ignored` are your sends in a state approval cannot move (already scheduled, sent, skipped, stopped or overwritten), and `notFound` are ids that do not exist, are not yours, or belong to a deleted campaign. Approving is the one decision that causes a message to be sent. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `422` `VALIDATION_FAILED` — sendIds is missing, empty, longer than 100, contains a duplicate, or an entry is not a 24-character hex id; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sendIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A queued send id (24-character hex ObjectId)."
                    },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "1-100 unique queued-send ids. Approve moves rows in approval_required to scheduled; decline moves rows in approval_required or scheduled to stopped, which also halts that contact's sequence. Ids you do not own are reported under notFound; ids in a state the decision cannot move are reported under ignored."
                  }
                },
                "required": [
                  "sendIds"
                ]
              }
            }
          }
        }
      }
    },
    "/business/scheduled-sends/decline": {
      "post": {
        "operationId": "declineScheduledSends",
        "summary": "Decline queued sends awaiting review",
        "tags": [
          "Scheduled sends"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "declined": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Ids that moved to stopped, halting that contact's sequence."
                    },
                    "ignored": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Your sends that decline cannot move in their current state."
                    },
                    "notFound": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Ids that do not exist or belong to a campaign you do not own."
                    }
                  },
                  "required": [
                    "declined",
                    "ignored",
                    "notFound"
                  ]
                },
                "example": {
                  "declined": [
                    "6a8dce70a4566f4f2454bd4f"
                  ],
                  "ignored": [
                    "6a8da7adafc401ca94530e14"
                  ],
                  "notFound": [
                    "000000000000000000000001"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Declines queued sends. A declined row moves to `stopped`, which is TERMINAL for that contact: unlike skip, the sequence does not advance, so no further step is scheduled for the contact in this campaign. Decline reaches both AI drafts awaiting review (`approval_required`) and ordinary queued rows (`scheduled`), so it is also how you call off an upcoming send for one contact. Only sends belonging to campaigns you own can be declined. The answer reports every id you passed: `declined` are the ones that moved, `ignored` are your sends in a state decline cannot move (already sent, skipped, stopped or overwritten), and `notFound` are ids that do not exist, are not yours, or belong to a deleted campaign. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `422` `VALIDATION_FAILED` — sendIds is missing, empty, longer than 100, contains a duplicate, or an entry is not a 24-character hex id; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sendIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "description": "A queued send id (24-character hex ObjectId)."
                    },
                    "minItems": 1,
                    "maxItems": 100,
                    "description": "1-100 unique queued-send ids. Approve moves rows in approval_required to scheduled; decline moves rows in approval_required or scheduled to stopped, which also halts that contact's sequence. Ids you do not own are reported under notFound; ids in a state the decision cannot move are reported under ignored."
                  }
                },
                "required": [
                  "sendIds"
                ]
              }
            }
          }
        }
      }
    },
    "/business/campaign-templates": {
      "get": {
        "operationId": "listCampaignTemplates",
        "summary": "The workspace's saved campaign templates",
        "tags": [
          "Campaign templates"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "templates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "name": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "ai-generated",
                              "manual"
                            ],
                            "description": "The campaignType a campaign built from this template will carry."
                          },
                          "timezone": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "emailDays": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "emailStartHour": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Start of the daily sending window, local to `timezone`."
                          },
                          "emailEndHour": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "listIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Source lists captured when the template was saved."
                          },
                          "generalTopic": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The overall brief captured from an AI campaign; null for a manual one."
                          },
                          "createdAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "steps": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "sequenceNumber": {
                                  "type": [
                                    "integer",
                                    "null"
                                  ],
                                  "description": "0-based slot in the snapshotted sequence."
                                },
                                "channel": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "daysBetween": {
                                  "type": [
                                    "integer",
                                    "null"
                                  ]
                                },
                                "topic": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Empty string on a manual step that never had a topic."
                                },
                                "subject": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                },
                                "body": {
                                  "type": [
                                    "string",
                                    "null"
                                  ]
                                }
                              },
                              "required": [
                                "id",
                                "sequenceNumber",
                                "channel",
                                "daysBetween",
                                "topic",
                                "subject",
                                "body"
                              ]
                            },
                            "description": "The snapshotted sequence. A snapshot stores fewer fields than a live step - no step type, title or cc."
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "type",
                          "timezone",
                          "emailDays",
                          "emailStartHour",
                          "emailEndHour",
                          "listIds",
                          "generalTopic",
                          "createdAt",
                          "steps"
                        ]
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": {
                          "type": "integer",
                          "description": "1-based page number this response covers."
                        },
                        "pageSize": {
                          "type": "integer",
                          "description": "Rows requested per page."
                        },
                        "total": {
                          "type": "integer",
                          "description": "Total rows matching the query."
                        },
                        "totalPages": {
                          "type": "integer",
                          "description": "Total pages at this page size."
                        }
                      },
                      "required": [
                        "page",
                        "pageSize",
                        "total",
                        "totalPages"
                      ]
                    }
                  },
                  "required": [
                    "templates",
                    "pagination"
                  ]
                },
                "example": {
                  "templates": [
                    {
                      "id": "6a8dcc00f12e15c575d68c57",
                      "name": "SaaS cold intro",
                      "type": "manual",
                      "timezone": "UTC",
                      "emailDays": [
                        "Monday",
                        "Tuesday",
                        "Wednesday",
                        "Thursday",
                        "Friday"
                      ],
                      "emailStartHour": "09:00",
                      "emailEndHour": "17:00",
                      "listIds": [
                        "6a1edba88936e0fe1b20287c"
                      ],
                      "generalTopic": null,
                      "createdAt": "2026-08-25T17:08:16.290Z",
                      "steps": [
                        {
                          "id": "6a8dcc00f12e15c575d68c55",
                          "sequenceNumber": 0,
                          "channel": "email",
                          "daysBetween": 0,
                          "topic": "",
                          "subject": "Quick question about {Contact Company}",
                          "body": "<p>Hi {Contact First Name}, ...</p>"
                        },
                        {
                          "id": "6a8dcc00f12e15c575d68c56",
                          "sequenceNumber": 1,
                          "channel": "email",
                          "daysBetween": 2,
                          "topic": "",
                          "subject": "Following up",
                          "body": "<p>Circling back on my note.</p>"
                        }
                      ]
                    }
                  ],
                  "pagination": {
                    "page": 1,
                    "pageSize": 100,
                    "total": 42,
                    "totalPages": 1
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Lists the saved campaign templates you can see - your own plus those shared by your team's visibility settings - newest first, with the schedule settings and the full step sequence each one snapshots. Pass a template's `id` as `templateId` when creating a campaign to copy its steps and channels. This endpoint returns at most the 100 most recent templates; `pagination.total` tells you whether there are more. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      },
      "post": {
        "operationId": "createCampaignTemplate",
        "summary": "Save a campaign's sequence as a reusable template",
        "tags": [
          "Campaign templates"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "template": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Id of the new template."
                        }
                      },
                      "required": [
                        "id"
                      ]
                    }
                  },
                  "required": [
                    "template"
                  ]
                },
                "example": {
                  "template": {
                    "id": "6a8dce56a4566f4f2454bd19"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Saves an existing campaign's sequence as a reusable template: every step (channel, wait days, topic, subject and body) plus the schedule settings - sending days, sending hours, timezone and source lists. The template is a snapshot; later edits to the campaign do not change it, and editing the template is not exposed here. Use the returned id as `templateId` when creating a campaign. Only the token owner's own campaigns can be snapshotted: a campaign delegated to you, one shared by your team's visibility settings, and a deleted one all answer 404. Rate limit: 30 requests/minute and 1,000/day per token owner, shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint.\n\nErrors:\n- `404` `CAMPAIGN_NOT_FOUND` — No campaign with this id exists, it belongs to another account (including a campaign delegated to you or shared by your team's visibility settings), or it has been deleted.\n- `422` `VALIDATION_FAILED` — `name` or `campaignId` is missing, unknown key, or campaignId is not a 24-character hex id; `param` names the field.\n- `429` `RATE_LIMITED` — More than 30 campaign requests in a minute, or 1,000 in a day, for this token owner (the bucket is shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call).\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200,
                    "description": "Name of the new template (1-200 characters, trimmed)."
                  },
                  "campaignId": {
                    "type": "string",
                    "description": "Id of the campaign whose steps (channel, wait days, topic, subject/body) and schedule settings (emailDays, sending hours, timezone, source lists) are snapshotted into the template."
                  }
                },
                "required": [
                  "name",
                  "campaignId"
                ]
              }
            }
          }
        }
      }
    },
    "/business/campaign-templates/{campaignTemplateId}": {
      "delete": {
        "operationId": "deleteCampaignTemplate",
        "summary": "Delete a template",
        "tags": [
          "Campaign templates"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "campaignTemplateId",
            "in": "path",
            "required": true,
            "description": "The campaign template's id (the _id of a GET /business/campaign-templates row, 24-character hex ObjectId).",
            "schema": {
              "type": "string",
              "description": "The campaign template's id (the _id of a GET /business/campaign-templates row, 24-character hex ObjectId)."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Deletes a saved campaign template. Campaigns already created from it are unaffected - a campaign copies the template's steps at creation and keeps no link to it. Rate limit: this endpoint has a tighter cap of 20 requests/minute and 500/day, applied inside the shared campaigns bucket of 30 requests/minute and 1,000/day per token owner (shared by every campaign, scheduled-send, campaign-template and knowledge-hub endpoint).\n\nErrors:\n- `404` `TEMPLATE_NOT_FOUND` — No template with this id exists, or it is not visible to you.\n- `422` `VALIDATION_FAILED` — campaignTemplateId is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Either this endpoint's own cap (20 requests/minute, 500/day) or the shared campaigns bucket (30/minute, 1,000/day for this token owner, shared by every /business/campaigns, /business/scheduled-sends, /business/campaign-templates and /business/knowledge-hubs call) was exceeded. The RateLimit-* headers on the response describe the shared bucket, so a refusal from this endpoint's own cap can still report requests remaining and carries no Retry-After.\n- `500` `UNEXPECTED_ERROR` — An unhandled failure; the detail stays in our logs and is never returned.\n\nRequires one of the following token scopes: campaigns."
      }
    },
    "/business/agents/signal-types": {
      "get": {
        "operationId": "listAgentTypes",
        "summary": "The agent kinds the wizard offers",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "signalTypes"
                  ],
                  "properties": {
                    "signalTypes": {
                      "type": "array",
                      "minItems": 18,
                      "maxItems": 18,
                      "items": {
                        "type": "object",
                        "required": [
                          "type",
                          "title",
                          "category"
                        ],
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": [
                              "web-monitor",
                              "person-starting-new-job",
                              "linkedin-posts",
                              "person-discovery-via-filters",
                              "job-postings",
                              "job-posting-in-location",
                              "first-person-hired-in-company-department",
                              "first-person-hired-internationally",
                              "company-headcount-growth",
                              "company-headcount-growth-over-baseline",
                              "company-department-headcount",
                              "company-employee-job-location-in-two-countries",
                              "funding-announcements",
                              "people-watcher",
                              "companies-watcher",
                              "job-changes-watcher",
                              "linkedin-profile",
                              "linkedin-post"
                            ],
                            "description": "The slug to POST to at /business/agents/{type}."
                          },
                          "title": {
                            "type": "string",
                            "description": "Human-readable name of the agent kind."
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "signal",
                              "watcher",
                              "scrape"
                            ],
                            "description": "signal = watches the market; watcher = watches one of your existing lists; scrape = one-shot LinkedIn engagement scrape."
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "signalTypes": [
                    {
                      "type": "web-monitor",
                      "title": "Website monitor",
                      "category": "signal"
                    },
                    {
                      "type": "person-starting-new-job",
                      "title": "Person starting a new job",
                      "category": "signal"
                    },
                    {
                      "type": "linkedin-posts",
                      "title": "LinkedIn posts by topic",
                      "category": "signal"
                    },
                    {
                      "type": "person-discovery-via-filters",
                      "title": "Person discovery via filters",
                      "category": "signal"
                    },
                    {
                      "type": "job-postings",
                      "title": "Job postings by company",
                      "category": "signal"
                    },
                    {
                      "type": "job-posting-in-location",
                      "title": "Job postings in a location",
                      "category": "signal"
                    },
                    {
                      "type": "first-person-hired-in-company-department",
                      "title": "First hire in a department",
                      "category": "signal"
                    },
                    {
                      "type": "first-person-hired-internationally",
                      "title": "First international hire",
                      "category": "signal"
                    },
                    {
                      "type": "company-headcount-growth",
                      "title": "Company headcount growth",
                      "category": "signal"
                    },
                    {
                      "type": "company-headcount-growth-over-baseline",
                      "title": "Headcount growth over baseline",
                      "category": "signal"
                    },
                    {
                      "type": "company-department-headcount",
                      "title": "Department headcount",
                      "category": "signal"
                    },
                    {
                      "type": "company-employee-job-location-in-two-countries",
                      "title": "Employees across two countries",
                      "category": "signal"
                    },
                    {
                      "type": "funding-announcements",
                      "title": "Funding announcements",
                      "category": "signal"
                    },
                    {
                      "type": "people-watcher",
                      "title": "People watcher (from a list)",
                      "category": "watcher"
                    },
                    {
                      "type": "companies-watcher",
                      "title": "Companies watcher (from a list)",
                      "category": "watcher"
                    },
                    {
                      "type": "job-changes-watcher",
                      "title": "Job-changes watcher (from a list)",
                      "category": "watcher"
                    },
                    {
                      "type": "linkedin-profile",
                      "title": "LinkedIn profile scrape",
                      "category": "scrape"
                    },
                    {
                      "type": "linkedin-post",
                      "title": "LinkedIn post scrape",
                      "category": "scrape"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The 18 agent kinds this API can create, grouped by `category`: `signal` (13 market monitors watching job changes, LinkedIn posts, job postings, headcount, funding or the open web), `watcher` (3 kinds that watch the people or companies of one of your EXISTING lists) and `scrape` (2 one-shot LinkedIn engagement scrapes). `type` is the slug to POST to `/business/agents/{type}`; that operation's request body is the kind's own config. Static catalogue — it reads no account data and never changes between calls. Counts against the agents rate-limit bucket (30/min, 2,000/day).\n\nErrors:\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      }
    },
    "/business/agents": {
      "get": {
        "operationId": "listAgents",
        "summary": "The token owner's agents across every kind",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size: how many agents to return per page (1-100, default 25).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 25,
              "description": "Page size: how many agents to return per page (1-100, default 25)."
            }
          },
          {
            "name": "pageNum",
            "in": "query",
            "required": false,
            "description": "1-based page number (default 1); agents are ordered newest-created first. `pagination.totalPages` tells you when to stop.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based page number (default 1); agents are ordered newest-created first. `pagination.totalPages` tells you when to stop."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agents",
                    "pagination"
                  ],
                  "properties": {
                    "agents": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "type",
                          "name",
                          "status",
                          "entityType",
                          "listId",
                          "sourceListIds",
                          "contactsFound",
                          "maxContacts",
                          "expirationDate",
                          "folderId",
                          "createdAt",
                          "updatedAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The agent's id — pass it as `{agentId}` to every other agent operation."
                          },
                          "type": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "web-monitor",
                              "person-starting-new-job",
                              "linkedin-posts",
                              "person-discovery-via-filters",
                              "job-postings",
                              "job-posting-in-location",
                              "first-person-hired-in-company-department",
                              "first-person-hired-internationally",
                              "company-headcount-growth",
                              "company-headcount-growth-over-baseline",
                              "company-department-headcount",
                              "company-employee-job-location-in-two-countries",
                              "funding-announcements",
                              "people-watcher",
                              "companies-watcher",
                              "job-changes-watcher",
                              "linkedin-profile",
                              "linkedin-post",
                              null
                            ],
                            "description": "The public agent kind — the same slug you POST to at /business/agents/{type}. null for a legacy kind this API no longer offers."
                          },
                          "name": {
                            "type": "string",
                            "description": "The agent's name, which is also the name of the results list it delivers into."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "initializing",
                              "processing",
                              "active",
                              "paused",
                              "expired",
                              "failed",
                              "completed",
                              "deleted"
                            ],
                            "description": "initializing = saved draft, nothing billed; processing = a run is under way; active = running; paused = stopped by you; expired = past its expirationDate; failed = the provider setup failed. Older agents can also read `completed` (a one-off scrape that has finished) and `deleted` (an agent deleted before deletions were timestamped: still readable, but it can no longer be edited or activated)."
                          },
                          "entityType": {
                            "type": "string",
                            "enum": [
                              "person",
                              "company"
                            ],
                            "description": "What the agent delivers into its results list: people or companies."
                          },
                          "listId": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The results list this agent delivers into; read the delivered rows with the Lists endpoints. null while the agent is still a draft."
                          },
                          "sourceListIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Watcher kinds only: the existing lists being watched. Empty for every other kind."
                          },
                          "contactsFound": {
                            "type": "integer",
                            "description": "How many results the agent has delivered into its list so far."
                          },
                          "maxContacts": {
                            "type": [
                              "integer",
                              "null"
                            ],
                            "description": "The delivery cap set at creation, or null for no cap."
                          },
                          "expirationDate": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "ISO-8601 timestamp at which the agent stops running, or null when it runs until paused or deleted."
                          },
                          "folderId": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The agent folder this agent sits in, or null when it is unfiled."
                          },
                          "createdAt": {
                            "type": "string",
                            "description": "ISO-8601 creation timestamp. Agents are returned newest-created first."
                          },
                          "updatedAt": {
                            "type": "string",
                            "description": "ISO-8601 timestamp of the last change to the agent."
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "required": [
                        "pageNum",
                        "totalPages",
                        "totalRecords"
                      ],
                      "properties": {
                        "pageNum": {
                          "type": "integer",
                          "description": "The page this answer represents (1-based)."
                        },
                        "totalPages": {
                          "type": "integer",
                          "description": "How many pages exist at the current `limit`."
                        },
                        "totalRecords": {
                          "type": "integer",
                          "description": "Total agents the token owner has."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agents": [
                    {
                      "id": "6a8d7b0032fd7470039135a9",
                      "type": "web-monitor",
                      "name": "Web Monitor Sofiia 25aug",
                      "status": "active",
                      "entityType": "company",
                      "listId": "6a8d7b01c5017e82fb6058d9",
                      "sourceListIds": [],
                      "contactsFound": 1,
                      "maxContacts": 50,
                      "expirationDate": null,
                      "folderId": null,
                      "createdAt": "2026-08-25T11:22:41.629Z",
                      "updatedAt": "2026-08-25T11:23:12.407Z"
                    },
                    {
                      "id": "6a8d7a5032fd74700391356b",
                      "type": "companies-watcher",
                      "name": "Fundraising Sofiia 25 aug",
                      "status": "paused",
                      "entityType": "company",
                      "listId": "6a8d7a55c5017e82fb605534",
                      "sourceListIds": [
                        "6a7ef6d7d1d092349bbf5db5"
                      ],
                      "contactsFound": 0,
                      "maxContacts": 50,
                      "expirationDate": "2026-08-26T00:00:00.000Z",
                      "folderId": null,
                      "createdAt": "2026-08-25T11:19:44.831Z",
                      "updatedAt": "2026-08-25T11:21:07.334Z"
                    }
                  ],
                  "pagination": {
                    "pageNum": 1,
                    "totalPages": 210,
                    "totalRecords": 628
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Your agents of every kind, newest created first, one page at a time. `type` is the public slug (the same one you POST to at /business/agents/{type}); `status` is `initializing` for a saved draft, then `processing` / `active` / `paused` / `expired` / `failed`; older agents can also read `completed` or `deleted`. `contactsFound` is how many results the agent has delivered so far and `listId` is the list holding them — read the rows with the Lists endpoints. `sourceListIds` is filled only for the watcher kinds, which watch an existing list. Use `limit` (1-100, default 25) and `pageNum` with `pagination.totalPages` to walk the whole set. The agent's config is not included here: read it with GET /business/agents/{agentId}.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request failed this endpoint's own validation — `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      }
    },
    "/business/agents/web-monitor": {
      "post": {
        "operationId": "createWebMonitorAgent",
        "summary": "Create a web monitor agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "web-monitor"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927a",
                    "type": "web-monitor",
                    "name": "Regulator fines 2026",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Website monitor agent (`web-monitor`). Runs a natural-language web search every `searchPeriod` (default daily) over up to `numResults` pages and delivers matching people or companies (`entityType`); each delivered result costs 50 credits and `maxCreditSpend` bounds a run. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `422` `AGENT_SIGNAL_REJECTED` — web-monitor only: the search provider refused the `prompt` as a searchable signal. Rewrite the prompt rather than retrying it.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "entityType": {
                    "type": "string",
                    "enum": [
                      "person",
                      "company"
                    ],
                    "description": "What the monitor should find: 'person' for people, 'company' for companies."
                  },
                  "prompt": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Plain-language description of the signal to watch for on the open web (e.g. 'companies fined by a regulator over late supplier payments'). Including the year — 'in 2026' — materially improves recency."
                  },
                  "searchPeriod": {
                    "type": "string",
                    "enum": [
                      "1h",
                      "6h",
                      "1d",
                      "7d"
                    ],
                    "description": "How often the search re-runs — use one of exactly: 1h, 6h, 1d, 7d. Defaults to 1d."
                  },
                  "numResults": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "description": "Web pages to read per run (1-100, defaults to 10). This caps PAGES, not results — one page can yield several matches."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  }
                },
                "required": [
                  "listName",
                  "entityType",
                  "prompt"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/person-starting-new-job": {
      "post": {
        "operationId": "createPersonStartingNewJobAgent",
        "summary": "Create a person starting new job agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "person-starting-new-job"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927b",
                    "type": "person-starting-new-job",
                    "name": "Fintech CFO job changes",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Person starting a new job agent (`person-starting-new-job`). Watches one industry for people who just changed jobs and delivers them (optionally with reactor data) in batches of `notificationCount`. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Industry the person works in. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "authorCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Companies the person is starting at, as company LinkedIn URLs, for example [\"https://www.linkedin.com/company/google/\"]. This filter resolves URLs only: a bare company name or domain is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple URLs are OR-joined (a move into any listed company matches) and there is no cap. Preferred over the deprecated `currentCompany`."
                  },
                  "authorTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Job title the person is starting in. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\", \"CEO\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined (a move into any of them matches) and there is no cap. Preferred over the deprecated `currentTitle`."
                  },
                  "currentCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Deprecated, use `authorCompany`. Read only when `authorCompany` is omitted, and then sent as the author-company filter, which resolves company LinkedIn URLs only, for example \"https://www.linkedin.com/company/google/\": the bare name or domain this field is named after is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple URLs are OR-joined and there is no cap."
                  },
                  "pastCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Past employer of the person, as a company NAME or DOMAIN, for example [\"Google\"] or [\"google.com\"]. Free text resolved by the provider, so a name it cannot resolve is accepted, the create still answers 201, and the agent then silently matches nothing; a domain is the unambiguous form. Multiple values are OR-joined (a person who worked at any of them matches) and there is no cap."
                  },
                  "currentTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Deprecated, use `authorTitle`. Read only when `authorTitle` is omitted, and then sent as the author-title filter. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined and there is no cap."
                  },
                  "pastTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "A job title anywhere in the person's PAST work history. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\", \"CEO\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined (a person who held any of them matches) and there is no cap."
                  },
                  "leadCompanyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Size of the person's CURRENT employer, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple buckets are OR-joined (a person whose employer is in any listed band matches) and there is no cap."
                  },
                  "leadCompanyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Headquarters country of the person's CURRENT employer. Use values from the provider's canonical country list: full English country names such as \"United States\", \"United Kingdom\", \"Germany\". ISO codes like \"US\" are not accepted, no lookup endpoint serves this vocabulary yet, and an unrecognised name is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple countries are OR-joined (a person whose employer sits in any of them matches) and there is no cap."
                  },
                  "reactors": {
                    "type": "boolean",
                    "description": "Also deliver the people who REACTED to each matching post, not just its author. Reactions cost extra credits per delivered contact."
                  },
                  "detailedReactorData": {
                    "type": "boolean",
                    "description": "Enrich each delivered reactor with employer, education and summary data (only meaningful with `reactors: true`); costs more credits per contact."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  },
                  "enrichPhone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a phone number. Costs additional credits per contact enriched."
                  },
                  "enrichEmail": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a work email address. Costs additional credits per contact enriched."
                  }
                },
                "required": [
                  "listName",
                  "industries"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/linkedin-posts": {
      "post": {
        "operationId": "createLinkedinPostsAgent",
        "summary": "Create a linkedin posts agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "linkedin-posts"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927c",
                    "type": "linkedin-posts",
                    "name": "Posts about humanoid robotics",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a LinkedIn posts by topic agent (`linkedin-posts`). Delivers the authors (and optionally reactors) of LinkedIn posts matching `keywords`, narrowed by author/company filters. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "keywords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Free text matched against the POST TEXT. Each value is trimmed and lowercased, then all values are OR-joined into one provider query ([\"hiring\", \"humanoids\"] is sent as \"hiring OR humanoids\"), so a post matching ANY one of them qualifies; at least one keyword is required and there is no cap. A single value may itself carry boolean syntax: uppercase AND, OR and NOT, parentheses for grouping and double quotes for exact phrases, for example [\"\\\"product manager\\\" AND hiring\"]."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Size of the posting company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple buckets are OR-joined (a company in any listed band matches) and there is no cap. At least one of `companyHeadcount` or `companyCountries` must be set before this agent can start."
                  },
                  "companyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Headquarters country of the posting company. Use values from the provider's canonical country list: full English country names such as \"United States\", \"United Kingdom\", \"Germany\". ISO codes like \"US\" are not accepted, no lookup endpoint serves this vocabulary yet, and an unrecognised name is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple countries are OR-joined (a company headquartered in any of them matches) and there is no cap. At least one of `companyHeadcount` or `companyCountries` must be set before this agent can start."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 1,
                    "description": "Industry of the person or company posting. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. At most 1 value is allowed here; a second entry is rejected with 422 VALIDATION_FAILED."
                  },
                  "authorCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Companies the post author currently works at, as company LinkedIn URLs, for example [\"https://www.linkedin.com/company/google/\"]. This filter resolves URLs only: a bare company name or domain is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple URLs are OR-joined (a post by an employee of any listed company matches) and there is no cap. Preferred over the deprecated `currentCompany`."
                  },
                  "authorTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Current job title of the post author. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\", \"CEO\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined (a post by anyone holding any of them matches) and there is no cap. Preferred over the deprecated `currentTitle`."
                  },
                  "authorLocation": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 1,
                    "description": "Author location, matched geographically; at most one value, e.g. [\"United States\"]. Use exact values from GET /business/agents/autocomplete?field=region."
                  },
                  "actorType": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "person",
                        "company"
                      ]
                    },
                    "maxItems": 2,
                    "description": "Whether to match posts from people, companies or both (the default). At most one entry each of \"person\" and \"company\"."
                  },
                  "reactors": {
                    "type": "boolean",
                    "description": "Also deliver the people who REACTED to each matching post, not just its author. Reactions cost extra credits per delivered contact."
                  },
                  "detailedReactorData": {
                    "type": "boolean",
                    "description": "Enrich each delivered reactor with employer, education and summary data (only meaningful with `reactors: true`); costs more credits per contact."
                  },
                  "postIntent": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 1,
                    "description": "A single plain-language filter on the POST CONTENT itself, e.g. [\"announcing a new product launch\"]. It describes the post, never the person or company posting."
                  },
                  "postCategory": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Categories the post must fall into, for example [\"Business\", \"Personal\", \"Events\", \"Social Commentary\"]. Free text: the provider classifies every post with its own labels and files anything unmatched under \"Others\", so there is no fixed list and no endpoint to look one up, and a label it does not use is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple categories are OR-joined (a post in any of them matches); the provider caps this filter at 10 categories, and a longer array is accepted here and rejected upstream."
                  },
                  "currentCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Deprecated, use `authorCompany`. Read only when `authorCompany` is omitted, and then sent as the author-company filter, which resolves company LinkedIn URLs only, for example \"https://www.linkedin.com/company/google/\": the bare name or domain this field is named after is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple URLs are OR-joined and there is no cap."
                  },
                  "pastCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Past employer of the post author, as a company NAME or DOMAIN, for example [\"Google\"] or [\"google.com\"]. Free text resolved by the provider, so a name it cannot resolve is accepted, the create still answers 201, and the agent then silently matches nothing; a domain is the unambiguous form. Multiple values are OR-joined (an author who worked at any of them matches) and there is no cap."
                  },
                  "currentTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Deprecated, use `authorTitle`. Read only when `authorTitle` is omitted, and then sent as the author-title filter. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined and there is no cap."
                  },
                  "pastTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "A job title anywhere in the post author's PAST work history. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\", \"CEO\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined (an author who held any of them matches) and there is no cap."
                  },
                  "leadCompanyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Size of the post author's CURRENT employer, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple buckets are OR-joined (an author whose employer is in any listed band matches) and there is no cap."
                  },
                  "leadCompanyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Headquarters country of the post author's CURRENT employer. Use values from the provider's canonical country list: full English country names such as \"United States\", \"United Kingdom\", \"Germany\". ISO codes like \"US\" are not accepted, no lookup endpoint serves this vocabulary yet, and an unrecognised name is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple countries are OR-joined (an author whose employer sits in any of them matches) and there is no cap."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  },
                  "enrichPhone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a phone number. Costs additional credits per contact enriched."
                  },
                  "enrichEmail": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a work email address. Costs additional credits per contact enriched."
                  }
                },
                "required": [
                  "keywords",
                  "listName"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/person-discovery-via-filters": {
      "post": {
        "operationId": "createPersonDiscoveryViaFiltersAgent",
        "summary": "Create a person discovery via filters agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "person-discovery-via-filters"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927d",
                    "type": "person-discovery-via-filters",
                    "name": "Seed-stage founders in Berlin",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Person discovery via filters agent (`person-discovery-via-filters`). Delivers people matching the filter set; at least one filter must be non-empty. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Where the person is located, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple regions are OR-joined (a person in any of them matches) and there is no cap."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Industry the person works in. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Multiple industries are OR-joined (a person in any of them matches) and there is no cap."
                  },
                  "currentCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Current employer of the people to discover, as a company NAME or DOMAIN, for example [\"Google\"] or [\"google.com\"]. Free text resolved by the provider, so a name it cannot resolve is accepted, the create still answers 201, and the agent then silently matches nothing; a domain is the unambiguous form. Multiple values are OR-joined (a person at any of them matches) and there is no cap."
                  },
                  "pastCompany": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Past employer of the people to discover, as a company NAME or DOMAIN, for example [\"Google\"] or [\"google.com\"]. Free text resolved by the provider, so a name it cannot resolve is accepted, the create still answers 201, and the agent then silently matches nothing; a domain is the unambiguous form. Multiple values are OR-joined (a person who worked at any of them matches) and there is no cap."
                  },
                  "currentTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Current job title of the people to discover. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\", \"CEO\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined (a person holding any of them matches) and there is no cap."
                  },
                  "pastTitle": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "A job title anywhere in the person's PAST work history. Use exact values from GET /business/agents/autocomplete?field=title (for example \"Vice President of Sales\", \"CEO\"). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple titles are OR-joined (a person who held any of them matches) and there is no cap."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Size of the person's current employer, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple buckets are OR-joined (a person whose employer is in any listed band matches) and there is no cap."
                  },
                  "companyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Headquarters country of the person's current employer. Accepted values are full English country names, for example \"United States\", \"United Kingdom\", \"Germany\" — the vocabulary the app's own agent form sends for this filter. ISO codes such as \"US\" are not country names and match nothing, and no lookup endpoint serves this vocabulary: the agents autocomplete has no country field, and its `region` field returns LinkedIn geographies that include sub-national areas such as \"California, United States\", which are not country names. Nothing is checked against a list upstream, so an unrecognised value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple countries are OR-joined (a person whose employer sits in any of them matches) and there is no cap."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  },
                  "enrichPhone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a phone number. Costs additional credits per contact enriched."
                  },
                  "enrichEmail": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a work email address. Costs additional credits per contact enriched."
                  }
                },
                "required": [
                  "listName"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/job-postings": {
      "post": {
        "operationId": "createJobPostingsAgent",
        "summary": "Create a job postings agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "job-postings"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927e",
                    "type": "job-postings",
                    "name": "Companies hiring backend engineers",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Job postings by company agent (`job-postings`). Delivers companies posting jobs matching `titles`/`descriptions` in one region; at least one of the two is required. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Location the job is posted in, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "titles": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Free text, matched against the job POSTING TITLE, for example [\"Software Engineer\", \"Backend Developer\"]. Multiple values are OR-joined into a single provider keyword (\"Software Engineer OR Backend Developer\"), so a posting matching ANY one of them qualifies, and there is no cap. At least one of `titles` or `descriptions` is required. `exactKeywordMatch` (default true) decides whether the match is literal or semantic."
                  },
                  "descriptions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 1,
                    "description": "Free text: a single keyword or phrase that must appear in the job DESCRIPTION, for example [\"machine learning\"]. The value is trimmed and lowercased and sent verbatim, with no word splitting, so a phrase stays a phrase. At most 1 value is allowed; a second entry is rejected with 422 VALIDATION_FAILED. At least one of `titles` or `descriptions` is required. When `titles` is also present the provider searches on the title and applies this only as a secondary filter, and only while `exactKeywordMatch` is true."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Size of the hiring company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple buckets are OR-joined (a company in any listed band matches) and there is no cap."
                  },
                  "companyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Headquarters country of the hiring company. Use values from the provider's canonical country list: full English country names such as \"United States\", \"United Kingdom\", \"Germany\". ISO codes like \"US\" are not accepted, no lookup endpoint serves this vocabulary yet, and an unrecognised name is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple countries are OR-joined (a company headquartered in any of them matches) and there is no cap."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Industry of the hiring company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Multiple industries are OR-joined (a company in any of them matches) and there is no cap."
                  },
                  "exactKeywordMatch": {
                    "type": "boolean",
                    "default": true,
                    "description": "true (default) requires the `titles` / `descriptions` keywords to match exactly; false allows semantic matches."
                  },
                  "exactIndustryMatch": {
                    "type": "boolean",
                    "default": false,
                    "description": "true requires `industries` to match the company's industry exactly; false (default) allows semantic matches."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "regions"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/job-posting-in-location": {
      "post": {
        "operationId": "createJobPostingInLocationAgent",
        "summary": "Create a job posting in location agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "job-posting-in-location"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927f",
                    "type": "job-posting-in-location",
                    "name": "Hiring in the Nordics",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Job postings in a location agent (`job-posting-in-location`). Delivers companies posting jobs in one region, narrowed by industry/size/country. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Location the job is posted in, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Industry of the hiring company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Multiple industries are OR-joined (a company in any of them matches) and there is no cap."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Size of the hiring company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple buckets are OR-joined (a company in any listed band matches) and there is no cap."
                  },
                  "companyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Headquarters country of the hiring company. Use values from the provider's canonical country list: full English country names such as \"United States\", \"United Kingdom\", \"Germany\". ISO codes like \"US\" are not accepted, no lookup endpoint serves this vocabulary yet, and an unrecognised name is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple countries are OR-joined (a company headquartered in any of them matches) and there is no cap."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "regions"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/first-person-hired-in-company-department": {
      "post": {
        "operationId": "createFirstPersonHiredInCompanyDepartmentAgent",
        "summary": "Create a first person hired in company department agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "first-person-hired-in-company-department"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89280",
                    "type": "first-person-hired-in-company-department",
                    "name": "First sales hire",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a First hire in a department agent (`first-person-hired-in-company-department`). Delivers companies that made their first hire in `companyDepartment`. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "companyDepartment": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Department — use one of exactly: Accounting, Administrative, Arts and Design, Business Development, Community and Social Services, Consulting, Education, Engineering, Entrepreneurship, Finance, Healthcare Services, Human Resources, Information Technology, Legal, Marketing, Media and Communication, Military and Protective Services, Operations, Product Management, Program and Project Management, Purchasing, Quality Assurance, Real Estate, Research, Sales, Customer Success and Support."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Industry of the company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Headquarters location of the company, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Size of the company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "annualRevenue": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum annual revenue, in MILLIONS of the `subFilter` currency (1000 means $1B)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum annual revenue, in MILLIONS of the `subFilter` currency (10000 means $10B)."
                      },
                      "subFilter": {
                        "type": "string",
                        "enum": [
                          "USD"
                        ],
                        "description": "Currency the revenue bounds are expressed in. Only USD is supported."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Annual-revenue band of the company, in MILLIONS of USD: {\"min\": 1000, \"max\": 10000} means $1B to $10B. Both bounds are required whenever the object is sent, and `subFilter` must be one of exactly: USD, the default and the only currency the provider supports. Omit the whole object for no revenue filter."
                  },
                  "numOfFollowers": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Deprecated and ignored: it is only ever read as a fallback for `companyHeadcount`, which is required on this route and always wins, so arbitrary values here never reach the provider. Use `companyHeadcount`. Multiple values neither widen nor narrow the agent: the whole array is dropped before the provider call, so no OR or AND combination applies and no cap is enforced."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "companyDepartment",
                  "industries",
                  "regions",
                  "companyHeadcount"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/first-person-hired-internationally": {
      "post": {
        "operationId": "createFirstPersonHiredInternationallyAgent",
        "summary": "Create a first person hired internationally agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "first-person-hired-internationally"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89281",
                    "type": "first-person-hired-internationally",
                    "name": "First hire outside the US",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a First international hire agent (`first-person-hired-internationally`). Delivers companies that made their first hire outside their home country. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Industry of the company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Headquarters location of the company, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Size of the company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyHeadcountGrowth": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum year-over-year headcount growth, as a percentage (10 means 10%)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum year-over-year headcount growth, as a percentage (40 means 40%)."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Deprecated: accepted for backward compatibility and never forwarded to the provider, so arbitrary min and max values are allowed here and change nothing about what the agent matches. This monitor has no headcount-growth filter; constrain company size with `companyHeadcount` instead."
                  },
                  "annualRevenue": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum annual revenue, in MILLIONS of the `subFilter` currency (1000 means $1B)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum annual revenue, in MILLIONS of the `subFilter` currency (10000 means $10B)."
                      },
                      "subFilter": {
                        "type": "string",
                        "enum": [
                          "USD"
                        ],
                        "description": "Currency the revenue bounds are expressed in. Only USD is supported."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Annual-revenue band of the company, in MILLIONS of USD: {\"min\": 1000, \"max\": 10000} means $1B to $10B. Both bounds are required whenever the object is sent, and `subFilter` must be one of exactly: USD, the default and the only currency the provider supports. Omit the whole object for no revenue filter."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "industries",
                  "regions",
                  "companyHeadcount"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/company-headcount-growth": {
      "post": {
        "operationId": "createCompanyHeadcountGrowthAgent",
        "summary": "Create a company headcount growth agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "company-headcount-growth"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89282",
                    "type": "company-headcount-growth",
                    "name": "Fast-growing SaaS companies",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Company headcount growth agent (`company-headcount-growth`). Delivers companies whose headcount grew within `companyHeadcountGrowth` percent. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "companyHeadcountGrowth": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "minimum": 0,
                        "description": "Minimum year-over-year headcount growth, as a percentage (10 means 10%)."
                      },
                      "max": {
                        "type": "number",
                        "minimum": 0,
                        "description": "Maximum year-over-year headcount growth, as a percentage (40 means 40%)."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "The year-over-year headcount growth band to match, in PERCENT: {\"min\": 10, \"max\": 50} means companies that grew 10% to 50% YoY. Accepted values: any two numbers of 0 or more, with `min` less than or equal to `max` and no upper limit on `max`. Both bounds are required whenever the object is sent."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Industry of the company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Headquarters location of the company, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Size of the company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Deprecated: accepted for backward compatibility and never forwarded to the provider, so arbitrary values here change nothing about what the agent matches. Filter headquarters location with `regions` instead. Multiple values neither widen nor narrow the agent: the whole array is dropped before the provider call, so no OR or AND combination applies and no cap is enforced."
                  },
                  "annualRevenue": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum annual revenue, in MILLIONS of the `subFilter` currency (1000 means $1B)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum annual revenue, in MILLIONS of the `subFilter` currency (10000 means $10B)."
                      },
                      "subFilter": {
                        "type": "string",
                        "enum": [
                          "USD"
                        ],
                        "description": "Currency the revenue bounds are expressed in. Only USD is supported."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Annual-revenue band of the company, in MILLIONS of USD: {\"min\": 1000, \"max\": 10000} means $1B to $10B. Both bounds are required whenever the object is sent, and `subFilter` must be one of exactly: USD, the default and the only currency the provider supports. Omit the whole object for no revenue filter."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "companyHeadcountGrowth",
                  "industries",
                  "regions",
                  "companyHeadcount"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/company-headcount-growth-over-baseline": {
      "post": {
        "operationId": "createCompanyHeadcountGrowthOverBaselineAgent",
        "summary": "Create a company headcount growth over baseline agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "company-headcount-growth-over-baseline"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89283",
                    "type": "company-headcount-growth-over-baseline",
                    "name": "Doubled since 75 employees",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Headcount growth over baseline agent (`company-headcount-growth-over-baseline`). Delivers companies that grew `companyHeadcountGrowthFromBaseline` percent over `baselineHeadcount` within `timeframe`. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Headquarters location of the company, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "timeframe": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "The interval the growth is measured over. Use one of exactly: YoY, MoM, QoQ, 6M, 2Y. Long forms are also accepted, case-insensitively, and normalised before the provider call (\"year over year\" and \"12 months\" become YoY, \"month over month\" MoM, \"quarter over quarter\" QoQ, \"6 months\" 6M, \"2 years\" 2Y); anything else is passed through unchanged and rejected by the provider. Exactly one value is allowed (min 1, max 1)."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Industry of the company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "baselineHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "The historical headcount to measure growth from: an absolute employee count, not a percentage, for example [75] or [1000]. Exactly one number is allowed (min 1, max 1); a second entry is rejected with 422 VALIDATION_FAILED."
                  },
                  "companyHeadcountGrowthFromBaseline": {
                    "type": "array",
                    "items": {
                      "type": "number"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "The growth over `baselineHeadcount` that triggers a match, in PERCENT: [25] means the headcount has to be 25% above the baseline. Exactly one number is allowed (min 1, max 1); a second entry is rejected with 422 VALIDATION_FAILED."
                  },
                  "annualRevenue": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum annual revenue, in MILLIONS of the `subFilter` currency (1000 means $1B)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum annual revenue, in MILLIONS of the `subFilter` currency (10000 means $10B)."
                      },
                      "subFilter": {
                        "type": "string",
                        "enum": [
                          "USD"
                        ],
                        "description": "Currency the revenue bounds are expressed in. Only USD is supported."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Annual-revenue band of the company, in MILLIONS of USD: {\"min\": 1000, \"max\": 10000} means $1B to $10B. Both bounds are required whenever the object is sent, and `subFilter` must be one of exactly: USD, the default and the only currency the provider supports. Omit the whole object for no revenue filter."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "regions",
                  "timeframe",
                  "industries",
                  "baselineHeadcount",
                  "companyHeadcountGrowthFromBaseline"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/company-department-headcount": {
      "post": {
        "operationId": "createCompanyDepartmentHeadcountAgent",
        "summary": "Create a company department headcount agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "company-department-headcount"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89284",
                    "type": "company-department-headcount",
                    "name": "Companies with 10-50 in Sales",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Department headcount agent (`company-department-headcount`). Delivers companies whose `departmentHeadcount.department` sits within the given size range. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "departmentHeadcount": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum number of people in the named department."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum number of people in the named department."
                      },
                      "department": {
                        "type": "string",
                        "description": "Department — use one of exactly: Accounting, Administrative, Arts and Design, Business Development, Community and Social Services, Consulting, Education, Engineering, Entrepreneurship, Finance, Healthcare Services, Human Resources, Information Technology, Legal, Marketing, Media and Communication, Military and Protective Services, Operations, Product Management, Program and Project Management, Purchasing, Quality Assurance, Real Estate, Research, Sales, Customer Success and Support."
                      }
                    },
                    "required": [
                      "min",
                      "max",
                      "department"
                    ],
                    "description": "The department and the headcount band to watch, for example {\"department\": \"Sales\", \"min\": 10, \"max\": 50}. `min` and `max` are absolute people counts (not percentages) and are both required; `department` must be one of exactly the 26 department names listed on that property, spelled and cased the same way. Any other department string is accepted, the create still answers 201, and the agent then silently matches nothing."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Industry of the company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Headquarters location of the company, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "maxItems": 1,
                    "description": "Size of the whole company (at most one value). Options: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+."
                  },
                  "annualRevenue": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum annual revenue, in MILLIONS of the `subFilter` currency (1000 means $1B)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum annual revenue, in MILLIONS of the `subFilter` currency (10000 means $10B)."
                      },
                      "subFilter": {
                        "type": "string",
                        "enum": [
                          "USD"
                        ],
                        "description": "Currency the revenue bounds are expressed in. Only USD is supported."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Annual-revenue band of the company, in MILLIONS of USD: {\"min\": 1000, \"max\": 10000} means $1B to $10B. Both bounds are required whenever the object is sent, and `subFilter` must be one of exactly: USD, the default and the only currency the provider supports. Omit the whole object for no revenue filter."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "departmentHeadcount",
                  "industries",
                  "regions"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/company-employee-job-location-in-two-countries": {
      "post": {
        "operationId": "createCompanyEmployeeJobLocationInTwoCountriesAgent",
        "summary": "Create a company employee job location in two countries agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "company-employee-job-location-in-two-countries"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89285",
                    "type": "company-employee-job-location-in-two-countries",
                    "name": "US and India engineering teams",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Employees across two countries agent (`company-employee-job-location-in-two-countries`). Delivers companies with employees in two countries. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Industry of the company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "regions": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Headquarters location of the company, as a LinkedIn geography: either a country (\"United States\") or a sub-national area (\"California, United States\"). Use exact values from GET /business/agents/autocomplete?field=region. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 1,
                    "description": "Size of the company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Exactly one value is allowed here (min 1, max 1); to cover several, run one agent per value."
                  },
                  "companyHeadcountGrowth": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum year-over-year headcount growth, as a percentage (10 means 10%)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum year-over-year headcount growth, as a percentage (40 means 40%)."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Deprecated: accepted for backward compatibility and never forwarded to the provider, so arbitrary min and max values are allowed here and change nothing about what the agent matches. This monitor has no headcount-growth filter; constrain company size with `companyHeadcount` instead."
                  },
                  "annualRevenue": {
                    "type": "object",
                    "properties": {
                      "min": {
                        "type": "number",
                        "description": "Minimum annual revenue, in MILLIONS of the `subFilter` currency (1000 means $1B)."
                      },
                      "max": {
                        "type": "number",
                        "description": "Maximum annual revenue, in MILLIONS of the `subFilter` currency (10000 means $10B)."
                      },
                      "subFilter": {
                        "type": "string",
                        "enum": [
                          "USD"
                        ],
                        "description": "Currency the revenue bounds are expressed in. Only USD is supported."
                      }
                    },
                    "required": [
                      "min",
                      "max"
                    ],
                    "description": "Annual-revenue band of the company, in MILLIONS of USD: {\"min\": 1000, \"max\": 10000} means $1B to $10B. Both bounds are required whenever the object is sent, and `subFilter` must be one of exactly: USD, the default and the only currency the provider supports. Omit the whole object for no revenue filter."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "industries",
                  "regions",
                  "companyHeadcount"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/funding-announcements": {
      "post": {
        "operationId": "createFundingAnnouncementsAgent",
        "summary": "Create a funding announcements agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "funding-announcements"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89286",
                    "type": "funding-announcements",
                    "name": "Series A announcements",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Funding announcements agent (`funding-announcements`). Delivers companies announcing funding of the given `fundingRoundTypes`; at least one of companyHeadcount/industries/companyCountries is required. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "fundingRoundTypes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Funding round types to watch. Use values from: pre_seed, seed, angel, series_a, series_b, series_c, series_d, series_e, series_f, series_g, series_h, series_i, series_j, series_unknown, private_equity, debt_financing, convertible_note, grant, corporate_round, equity_crowdfunding, product_crowdfunding, secondary_market, post_ipo_equity, post_ipo_debt, post_ipo_secondary, non_equity_assistance, initial_coin_offering, undisclosed. Multiple types are OR-joined (a round of any listed type matches) and there is no cap; pass [] to match every round type. The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing."
                  },
                  "companyHeadcount": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Size of the funded company, as a headcount bucket. Use one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1,000, 1,001-5,000, 5,001-10,000, 10,001+ (the commas and the exact spacing are part of the value: \"500-1000\" is not a bucket). The upstream stores the string as sent and never checks it against a list, so any other value is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple buckets are OR-joined (a company in any listed band matches) and there is no cap. At least one of `companyHeadcount`, `industries` or `companyCountries` is required."
                  },
                  "industries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Industry of the funded company. Use exact values from GET /business/agents/autocomplete?field=industry (for example \"Software Development\", \"Financial Services\"). Any other wording is first resolved to the closest supported LinkedIn industry (\"tech\" becomes \"Technology, Information and Internet\"), and a value with no match is dropped rather than rejected, so the filter silently widens instead of failing. Multiple industries are OR-joined (a company in any of them matches) and there is no cap. At least one of `companyHeadcount`, `industries` or `companyCountries` is required."
                  },
                  "companyCountries": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Headquarters country of the funded company. Use values from the provider's canonical country list: full English country names such as \"United States\", \"United Kingdom\", \"Germany\". ISO codes like \"US\" are not accepted, no lookup endpoint serves this vocabulary yet, and an unrecognised name is accepted, the create still answers 201, and the agent then silently matches nothing. Multiple countries are OR-joined (a company headquartered in any of them matches) and there is no cap. At least one of `companyHeadcount`, `industries` or `companyCountries` is required."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "notificationCount": {
                    "type": "integer",
                    "description": "Maximum results the agent may deliver in a single run. Must be a positive multiple of 50."
                  }
                },
                "required": [
                  "listName",
                  "fundingRoundTypes"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/people-watcher": {
      "post": {
        "operationId": "createPeopleWatcherAgent",
        "summary": "Create a people watcher agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "people-watcher"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89287",
                    "type": "people-watcher",
                    "name": "Champions to watch",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a People watcher (from a list) agent (`people-watcher`). Watches the PEOPLE of an existing list (exactly one of `listId`/`listIds`) for the chosen `eventType`, re-checking every `frequency` days; each watched contact is billed at activation and on every cycle. A missing or foreign source list answers 404 LIST_NOT_FOUND, and a source list with nothing watchable in it answers 422 AGENT_SOURCE_LIST_EMPTY. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `404` `LIST_NOT_FOUND` — A source list named in `listId` / `listIds` does not exist or does not belong to the token owner.\n- `422` `AGENT_SOURCE_LIST_EMPTY` — The source list holds nothing this agent kind can watch — no LinkedIn URLs, no companies, or no trackable contacts. Fill the list first.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The existing SOURCE list(s) to watch, by id — the people/companies whose changes are tracked."
                  },
                  "listIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    },
                    "minItems": 1,
                    "description": "The existing SOURCE list(s) to watch, by id: the people whose changes are tracked. Each id is a list id from GET /business/lists. Every list you name is watched, their members are unioned and duplicate ids are collapsed, and there is no cap on how many lists; `listIds` and `listId` are mutually exclusive (sending both is rejected). A source list holding no contacts with a LinkedIn URL is rejected when the agent starts (422 AGENT_SOURCE_LIST_EMPTY)."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Name for BOTH the agent and the NEW dedicated results list this watcher creates. Must be unique — never reuse a source list's name; name it after the agent the user is creating."
                  },
                  "eventType": {
                    "type": "string",
                    "enum": [
                      "linkedin-person-profile-updates",
                      "linkedin-person-post-updates"
                    ],
                    "description": "Which change to watch on the people in the source list(s)."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "frequency": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90,
                    "default": 1,
                    "description": "How often the watcher checks its source list(s), in days (1-90, default 1). This is also its billing cadence."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "enrichPhone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a phone number. Costs additional credits per contact enriched."
                  },
                  "enrichEmail": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a work email address. Costs additional credits per contact enriched."
                  }
                },
                "required": [
                  "listName",
                  "eventType"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/companies-watcher": {
      "post": {
        "operationId": "createCompaniesWatcherAgent",
        "summary": "Create a companies watcher agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "companies-watcher"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89288",
                    "type": "companies-watcher",
                    "name": "Target accounts hiring",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Companies watcher (from a list) agent (`companies-watcher`). Watches the COMPANIES of an existing list (exactly one of `listId`/`listIds`) for the chosen `eventType`; job-posting watchers require at least one `keywords` entry and accept `jobPostingLocationTypes` (remote/on_site/hybrid). With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `404` `LIST_NOT_FOUND` — A source list named in `listId` / `listIds` does not exist or does not belong to the token owner.\n- `422` `AGENT_SOURCE_LIST_EMPTY` — The source list holds nothing this agent kind can watch — no LinkedIn URLs, no companies, or no trackable contacts. Fill the list first.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The existing SOURCE list(s) to watch, by id — the people/companies whose changes are tracked."
                  },
                  "listIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    },
                    "minItems": 1,
                    "description": "The existing SOURCE list(s) to watch, by id: the companies whose changes are tracked. Each id is a list id from GET /business/lists. Every list you name is watched, their members are unioned and duplicate ids are collapsed, and there is no cap on how many lists; `listIds` and `listId` are mutually exclusive (sending both is rejected). A source list holding no companies is rejected when the agent starts (422 AGENT_SOURCE_LIST_EMPTY)."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Name for BOTH the agent and the NEW dedicated results list this watcher creates. Must be unique — never reuse a source list's name; name it after the agent the user is creating."
                  },
                  "eventType": {
                    "type": "string",
                    "enum": [
                      "company-watch-linkedin-job-postings",
                      "company-watch-linkedin-posts",
                      "company-watch-press-mentions",
                      "company-watch-funding-milestones"
                    ],
                    "description": "Which change to watch on the companies in the source list(s)."
                  },
                  "expirationDate": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Date the agent stops running, as YYYY-MM-DD (for example \"2026-12-31\"), and in the future. Pass null to run until you pause or delete it; omit it for the default of one month from creation."
                  },
                  "keywords": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "description": "Free text, matched as a keyword against the job POSTING TITLE upstream, never against the description (for example [\"account executive\", \"sdr\"]). At least one is required when eventType is company-watch-linkedin-job-postings, and the value is ignored entirely by the other event types. Every value must be distinct and non-empty: a repeated keyword is refused with 422 (\"keywords must not contain duplicates\") and so is an empty string. Values are passed to the provider as written, so near-duplicates that differ only by surrounding spaces are accepted and both kept. No cap on how many you send."
                  },
                  "jobPostingLocationTypes": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "remote",
                        "on_site",
                        "hybrid"
                      ]
                    },
                    "minItems": 1,
                    "description": "Work arrangement of the job posting. Use one of exactly: remote, on_site, hybrid. Multiple values are OR-joined (a posting with any listed arrangement matches); there are only three values, so listing all three is the same as omitting the field, which matches any arrangement. Read only when eventType is company-watch-linkedin-job-postings."
                  },
                  "frequency": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 90,
                    "default": 1,
                    "description": "How often the watcher checks its source list(s), in days (1-90, default 1). This is also its billing cadence."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  }
                },
                "required": [
                  "listName",
                  "eventType"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/job-changes-watcher": {
      "post": {
        "operationId": "createJobChangesWatcherAgent",
        "summary": "Create a job changes watcher agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "job-changes-watcher"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d89289",
                    "type": "job-changes-watcher",
                    "name": "Customer job changes",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a Job-changes watcher (from a list) agent (`job-changes-watcher`). Watches the PEOPLE of an existing list for title/company changes against the provider's monthly dataset releases (exactly one of `listId`/`listIds`). With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `404` `LIST_NOT_FOUND` — A source list named in `listId` / `listIds` does not exist or does not belong to the token owner.\n- `422` `AGENT_SOURCE_LIST_EMPTY` — The source list holds nothing this agent kind can watch — no LinkedIn URLs, no companies, or no trackable contacts. Fill the list first.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "listId": {
                    "type": "string",
                    "minLength": 1,
                    "description": "The existing SOURCE list(s) to watch, by id — the people/companies whose changes are tracked."
                  },
                  "listIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    },
                    "minItems": 1,
                    "description": "The existing SOURCE list(s) to watch, by id: the people whose changes are tracked. Each id is a list id from GET /business/lists. Every list you name is watched and their members are unioned, and there is no cap on how many lists; `listIds` and `listId` are mutually exclusive (sending both is rejected). Unlike the people and companies watchers, this one REJECTS a repeated id rather than collapsing it (422 VALIDATION_FAILED, \"listIds must not contain duplicate list IDs\"), so name each list once. Only canonical contacts carrying a dataset identity are trackable, so manually created rows are skipped; source lists holding none of them are rejected when the agent starts (422 AGENT_SOURCE_LIST_EMPTY)."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "description": "Name for BOTH the agent and the NEW dedicated results list this watcher creates. Must be unique — never reuse a source list's name; name it after the agent the user is creating."
                  },
                  "maxContacts": {
                    "type": "integer",
                    "description": "Cap on the total number of results this agent delivers into its list. Omit for no cap."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  },
                  "enrichPhone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a phone number. Costs additional credits per contact enriched."
                  },
                  "enrichEmail": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a work email address. Costs additional credits per contact enriched."
                  }
                },
                "required": [
                  "listName"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/linkedin-profile": {
      "post": {
        "operationId": "createLinkedinProfileAgent",
        "summary": "Create a linkedin profile agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "linkedin-profile"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8928b",
                    "type": "linkedin-profile",
                    "name": "Competitor profile engagers",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a LinkedIn profile scrape agent (`linkedin-profile`). Scrapes the engagers (`fieldsToScrape`: likes/comments) of up to `maxPosts` recent posts from 1-50 profiles (exactly one of `profileUrl`/`profileUrls`), optionally on a recurring schedule. A started scrape answers with the agent's own `id`, like every other kind; its internal scrape job id never leaves the service. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "profileUrl": {
                    "type": "string",
                    "description": "One LinkedIn profile URL (https://www.linkedin.com/in/...). Provide exactly one of profileUrl or profileUrls."
                  },
                  "profileUrls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "Up to 50 unique LinkedIn profile URLs (https://www.linkedin.com/in/...). Provide exactly one of profileUrl or profileUrls."
                  },
                  "fieldsToScrape": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "likes",
                        "comments"
                      ]
                    },
                    "minItems": 1,
                    "description": "Which engagement to collect: \"likes\" (reactors), \"comments\" (commenters), or both. At least one is required."
                  },
                  "maxPosts": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 5,
                    "description": "How many of the profile's most recent posts to collect engagement from (1-100, default 5)."
                  },
                  "includeReposts": {
                    "type": "boolean",
                    "default": false,
                    "description": "Include the profile's reposts and quote posts. Off by default: engagement on a repost belongs to the original author's audience."
                  },
                  "postedLimit": {
                    "type": "string",
                    "enum": [
                      "24h",
                      "week",
                      "month",
                      "3months",
                      "year"
                    ],
                    "default": "year",
                    "description": "Only collect engagement from posts published within this window."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "enableRecurring": {
                    "type": "boolean",
                    "default": false,
                    "description": "Keep the scrape running on a recurring schedule instead of a single one-shot run."
                  },
                  "recurringExpiresAt": {
                    "type": "string",
                    "description": "ISO 8601 date-time at which a recurring scrape stops; must be in the future. Omit to keep it running until you stop it."
                  },
                  "enrichPhone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a phone number. Costs additional credits per contact enriched."
                  },
                  "enrichEmail": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a work email address. Costs additional credits per contact enriched."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  }
                },
                "required": [
                  "fieldsToScrape",
                  "listName"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/linkedin-post": {
      "post": {
        "operationId": "createLinkedinPostAgent",
        "summary": "Create a linkedin post agent",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "started"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The new agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "linkedin-post"
                          ],
                          "description": "The agent kind that was created — always this endpoint's own slug."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, echoed from `listName`; also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active"
                          ],
                          "description": "`initializing` when `start` was false (a draft). When `start` was true, the agent's real status right after starting: `processing` while the provider setup and first run are under way, `active` once it is running."
                        },
                        "started": {
                          "type": "boolean",
                          "description": "Echoes the `start` you sent: false = a draft that still has to be activated; true = already running and already billing."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8928c",
                    "type": "linkedin-post",
                    "name": "Launch post engagers",
                    "status": "initializing",
                    "started": false
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a LinkedIn post scrape agent (`linkedin-post`). Scrapes the engagers (`fieldsToScrape`: likes/comments) of 1-50 posts (exactly one of `postUrl`/`postUrls`), optionally every 7 days. A started scrape answers with the agent's own `id`, like every other kind; its internal scrape job id never leaves the service. With `start: false` (the default) a DRAFT is saved — status `initializing`, nothing billed: read it back with GET /business/agents/{agentId}, adjust it with PATCH /business/agents/{agentId}, then start it with POST /business/agents/{agentId}/activate. With `start: true` the agent is created AND started in one call: its dedicated results list is created, credits are checked and spent, and the provider subscriptions are set up. Either way the answer is 201 `{ agent: { id, type, name, status, started } }` — the same shape for every agent kind, draft or started. Poll GET /business/agents for `status` and `contactsFound`, and read the delivered rows with the Lists endpoints via the agent's `listId`. Free-plan accounts hold at most 10 agents, drafts included (403 AGENT_LIMIT_REACHED). Every field below is validated by the agents service: a rejected field answers 422 VALIDATION_FAILED, naming it in `param` and describing every failure in `message`. `listName` must not collide with an existing list or agent name (409 LIST_NAME_TAKEN), and starting without enough credits answers 402 INSUFFICIENT_CREDITS without creating anything.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request was rejected by validation. Either this endpoint's own request validation (a malformed body), or the agent config itself: a field missing, out of range or not one of the accepted values, or a business rule broken (an `expirationDate` that is not in the future, more industries than the kind accepts, a notification count out of range). `param` names the first offending field and `message` lists every failure.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "start": {
                    "type": "boolean",
                    "default": false,
                    "description": "true creates AND activates the agent (spends credits); false (default) saves a draft to activate later."
                  },
                  "postUrl": {
                    "type": "string",
                    "description": "One LinkedIn post URL (a /feed/update/, /posts/ or /pulse/ link). Provide exactly one of postUrl or postUrls."
                  },
                  "postUrls": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 50,
                    "description": "Up to 50 unique LinkedIn post URLs (/feed/update/, /posts/ or /pulse/ links). Provide exactly one of postUrl or postUrls."
                  },
                  "fieldsToScrape": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "likes",
                        "comments"
                      ]
                    },
                    "minItems": 1,
                    "description": "Which engagement to collect: \"likes\" (reactors), \"comments\" (commenters), or both. At least one is required."
                  },
                  "listName": {
                    "type": "string",
                    "description": "Name for BOTH the agent and the results list it creates. Must be unique across your agents: a name already in use is rejected with 409 LIST_NAME_TAKEN."
                  },
                  "enableRecurring": {
                    "type": "boolean",
                    "default": false,
                    "description": "Keep the scrape running on a recurring schedule instead of a single one-shot run."
                  },
                  "enrichPhone": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a phone number. Costs additional credits per contact enriched."
                  },
                  "enrichEmail": {
                    "type": "boolean",
                    "default": false,
                    "description": "Also enrich every delivered contact with a work email address. Costs additional credits per contact enriched."
                  },
                  "maxCreditSpend": {
                    "type": "integer",
                    "minimum": 1000,
                    "maximum": 200000,
                    "description": "Maximum credits this agent may spend in a single run or refresh (1000 to 200000); delivery-driven monitors stop once their total delivered results reach it. Omit for no limit."
                  }
                },
                "required": [
                  "fieldsToScrape",
                  "listName"
                ]
              }
            }
          }
        }
      }
    },
    "/business/agents/autocomplete": {
      "get": {
        "operationId": "autocompleteAgentField",
        "summary": "Canonical values for agent config filters",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "field",
            "in": "query",
            "required": true,
            "description": "Which vocabulary to search: region, industry, title or school. The returned strings are the exact values the agent config filters accept: region feeds `regions` and `authorLocation`, industry feeds `industries`, title feeds `currentTitle`, `pastTitle` and `authorTitle`. There is no country vocabulary here: region returns LinkedIn geographies that include sub-national areas such as \"California, United States\", so it is not a source for `companyCountries` or `leadCompanyCountries`, which take full English country names only.",
            "schema": {
              "type": "string",
              "enum": [
                "region",
                "industry",
                "title",
                "school"
              ],
              "description": "Which vocabulary to search: region, industry, title or school. The returned strings are the exact values the agent config filters accept: region feeds `regions` and `authorLocation`, industry feeds `industries`, title feeds `currentTitle`, `pastTitle` and `authorTitle`. There is no country vocabulary here: region returns LinkedIn geographies that include sub-national areas such as \"California, United States\", so it is not a source for `companyCountries` or `leadCompanyCountries`, which take full English country names only."
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Free-text term to resolve, 1-200 characters (e.g. \"software\", \"united states\", \"vp of sales\"). At most 10 canonical values are returned, best match first; an empty array means no match.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "description": "Free-text term to resolve, 1-200 characters (e.g. \"software\", \"united states\", \"vp of sales\"). At most 10 canonical values are returned, best match first; an empty array means no match."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "field",
                    "suggestions"
                  ],
                  "properties": {
                    "field": {
                      "type": "string",
                      "enum": [
                        "region",
                        "industry",
                        "title",
                        "school"
                      ],
                      "description": "The vocabulary that was searched — echoed back from the request."
                    },
                    "suggestions": {
                      "type": "array",
                      "maxItems": 10,
                      "items": {
                        "type": "string"
                      },
                      "description": "Canonical values, best match first. Copy them verbatim into the agent config."
                    }
                  }
                },
                "example": {
                  "field": "region",
                  "suggestions": [
                    "United States",
                    "United States Minor Outlying Islands"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Resolves free text to the exact strings an agent config accepts, so a create body never fails on a near-miss spelling. `region` feeds `regions` and `authorLocation`; `industry` feeds `industries`; `title` feeds `currentTitle`, `pastTitle` and `authorTitle`; `school` is available for completeness. There is no country vocabulary: `region` returns LinkedIn geographies that include sub-national areas such as \"California, United States\", so it is NOT a source for `companyCountries` or `leadCompanyCountries` — those take full English country names only (\"United States\", \"Germany\") and no lookup endpoint serves them. Returns at most 10 values, best match first; an empty array means nothing matched — try a broader term. Counts against the agents bucket (30/min) and, upstream, a separate lookup bucket (120/min).\n\nErrors:\n- `400` `INVALID_REQUEST` — The agents service rejected the request for a reason this API does not model specifically. The request is not retryable unchanged.\n- `422` `VALIDATION_FAILED` — The request failed this endpoint's own validation — `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      }
    },
    "/business/agents/{agentId}": {
      "get": {
        "operationId": "getAgent",
        "summary": "An agent's config as the drawer shows it",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned.",
            "schema": {
              "type": "string",
              "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "config",
                        "isReconstructed",
                        "lossyFields",
                        "sourceLists"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "web-monitor",
                            "person-starting-new-job",
                            "linkedin-posts",
                            "person-discovery-via-filters",
                            "job-postings",
                            "job-posting-in-location",
                            "first-person-hired-in-company-department",
                            "first-person-hired-internationally",
                            "company-headcount-growth",
                            "company-headcount-growth-over-baseline",
                            "company-department-headcount",
                            "company-employee-job-location-in-two-countries",
                            "funding-announcements",
                            "people-watcher",
                            "companies-watcher",
                            "job-changes-watcher",
                            "linkedin-profile",
                            "linkedin-post",
                            null
                          ],
                          "description": "The public agent kind — the same slug you POST to at /business/agents/{type}. null for a legacy kind this API no longer offers."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, which is also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active",
                            "paused",
                            "expired",
                            "failed",
                            "completed",
                            "deleted"
                          ],
                          "description": "initializing = saved draft, nothing billed; processing = a run is under way; active = running; paused = stopped by you; expired = past its expirationDate; failed = the provider setup failed. Older agents can also read `completed` (a one-off scrape that has finished) and `deleted` (an agent deleted before deletions were timestamped: still readable, but it can no longer be edited or activated)."
                        },
                        "config": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The agent's config in CREATE shape: exactly the body you would POST to /business/agents/{type} (without `start`) to build this agent again. Its fields are the ones documented on that type's create operation."
                        },
                        "isReconstructed": {
                          "type": "boolean",
                          "description": "false = the config is the stored snapshot, returned verbatim (always the case for a draft). true = the agent was started before its snapshot existed and the config was rebuilt from the live record, so check `lossyFields`."
                        },
                        "lossyFields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Config fields that could not be recovered when `isReconstructed` is true; `[\"*\"]` means only `name` is known. Empty otherwise."
                        },
                        "sourceLists": {
                          "type": "array",
                          "description": "Watcher kinds only: the source lists the config names, resolved to their names. Empty for every other kind.",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "name"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "The source list's id."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The source list's name, or null when the list has been deleted."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927a",
                    "type": "web-monitor",
                    "name": "Regulator fines 2026",
                    "status": "initializing",
                    "config": {
                      "listName": "Regulator fines 2026",
                      "entityType": "company",
                      "prompt": "companies fined by a financial regulator in 2026",
                      "searchPeriod": "6h",
                      "numResults": 7
                    },
                    "isReconstructed": false,
                    "lossyFields": [],
                    "sourceLists": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "One agent with its config, in any status. `config` is the agent in CREATE shape: exactly the body you would POST to /business/agents/{type} (minus `start`) to build it again, and exactly what PATCH accepts. A draft returns the config you saved, verbatim (`isReconstructed: false`). An agent that was started before configs were snapshotted returns a best-effort reconstruction (`isReconstructed: true`) and names anything it could not recover in `lossyFields` (`[\"*\"]` means only the name survived) — fill those in with PATCH on a duplicate before activating it. `sourceLists` resolves a watcher's source lists to their names. This does NOT return delivered results: take `listId` from GET /business/agents and read the rows with the Lists endpoints.\n\nErrors:\n- `404` `AGENT_NOT_FOUND` — No agent with this id belongs to the token owner. A deleted agent and another user's agent answer identically.\n- `422` `VALIDATION_FAILED` — The request failed this endpoint's own validation — `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      },
      "patch": {
        "operationId": "updateAgent",
        "summary": "Update a draft agent's config (partial)",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned.",
            "schema": {
              "type": "string",
              "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "config",
                        "isReconstructed",
                        "lossyFields",
                        "sourceLists"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "web-monitor",
                            "person-starting-new-job",
                            "linkedin-posts",
                            "person-discovery-via-filters",
                            "job-postings",
                            "job-posting-in-location",
                            "first-person-hired-in-company-department",
                            "first-person-hired-internationally",
                            "company-headcount-growth",
                            "company-headcount-growth-over-baseline",
                            "company-department-headcount",
                            "company-employee-job-location-in-two-countries",
                            "funding-announcements",
                            "people-watcher",
                            "companies-watcher",
                            "job-changes-watcher",
                            "linkedin-profile",
                            "linkedin-post",
                            null
                          ],
                          "description": "The public agent kind — the same slug you POST to at /business/agents/{type}. null for a legacy kind this API no longer offers."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, which is also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active",
                            "paused",
                            "expired",
                            "failed",
                            "completed",
                            "deleted"
                          ],
                          "description": "initializing = saved draft, nothing billed; processing = a run is under way; active = running; paused = stopped by you; expired = past its expirationDate; failed = the provider setup failed. Older agents can also read `completed` (a one-off scrape that has finished) and `deleted` (an agent deleted before deletions were timestamped: still readable, but it can no longer be edited or activated)."
                        },
                        "config": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The agent's config in CREATE shape: exactly the body you would POST to /business/agents/{type} (without `start`) to build this agent again. Its fields are the ones documented on that type's create operation."
                        },
                        "isReconstructed": {
                          "type": "boolean",
                          "description": "false = the config is the stored snapshot, returned verbatim (always the case for a draft). true = the agent was started before its snapshot existed and the config was rebuilt from the live record, so check `lossyFields`."
                        },
                        "lossyFields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Config fields that could not be recovered when `isReconstructed` is true; `[\"*\"]` means only `name` is known. Empty otherwise."
                        },
                        "sourceLists": {
                          "type": "array",
                          "description": "Watcher kinds only: the source lists the config names, resolved to their names. Empty for every other kind.",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "name"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "The source list's id."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The source list's name, or null when the list has been deleted."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927a",
                    "type": "web-monitor",
                    "name": "Regulator fines 2026",
                    "status": "initializing",
                    "config": {
                      "listName": "Regulator fines 2026",
                      "entityType": "company",
                      "prompt": "companies fined by a financial regulator in 2026",
                      "searchPeriod": "6h",
                      "numResults": 7
                    },
                    "isReconstructed": false,
                    "lossyFields": [],
                    "sourceLists": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Partial update of a DRAFT agent's config. Send one or more of the agent type's own config fields — the same fields as its POST /business/agents/{type} body, without `start`. Keys are merged over the saved config: omitted fields keep their value, an array replaces the stored array, and unknown keys are dropped. Sending `listName` renames both the agent and the results list it will create. The merged config is re-validated against the type's schema, so a partial edit can still be rejected (422 VALIDATION_FAILED). Only drafts (`status: initializing`) are editable — a started, paused, expired or failed agent answers 409 AGENT_NOT_A_DRAFT, so duplicate it and edit the copy. Nothing is billed. The answer is the saved agent, in the same shape as GET /business/agents/{agentId}.\n\nErrors:\n- `404` `AGENT_NOT_FOUND` — No agent with this id belongs to the token owner. A deleted agent and another user's agent answer identically.\n- `409` `AGENT_NOT_A_DRAFT` — The agent is not a draft (status is not `initializing`): it was already started, or is paused, expired or failed. Only drafts are editable and activatable — duplicate the agent and work on the copy.\n- `409` `AGENT_CONFIG_MISSING` — The draft carries no stored config to work from (a legacy draft saved before configs were persisted). Create the agent again.\n- `409` `AGENT_TYPE_UNSUPPORTED` — The agent is of a legacy kind this API can no longer edit or activate; its `type` reads as null.\n- `422` `VALIDATION_FAILED` — The update was rejected by validation. Either this endpoint's own request validation (a malformed `agentId`, an empty body), where `param` names the offending field; or the merged config failed the agent type's own schema, which the agents service reports without per-field detail, so `param` is null and `message` is the generic one. Re-check the fields you sent against that type's create body.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "description": "One or more of the agent type's own config fields (the same fields as its POST /business/agents/{type} body, without `start`). Keys are merged over the draft's saved config: omitted fields keep their value, arrays replace the stored array. Only drafts (status \"initializing\") are editable (409 AGENT_NOT_A_DRAFT otherwise); the merged config is re-validated against the type's schema (422 VALIDATION_FAILED) and unknown keys are dropped."
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteAgent",
        "summary": "Delete an agent (409 while a run is processing)",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned.",
            "schema": {
              "type": "string",
              "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Deletes the agent and tears down the provider subscriptions behind it. The results list it built and the rows already delivered are KEPT — delete the list separately if you want them gone. Drafts delete immediately. An agent whose run is in progress (`status: processing`) answers 409 AGENT_PROCESSING; wait until it reads `active` or `paused` and retry. Nothing is refunded, and a deleted agent is not recoverable — duplicate it first if you may want it back. Answers 204 with no body.\n\nErrors:\n- `404` `AGENT_NOT_FOUND` — No agent with this id belongs to the token owner. A deleted agent and another user's agent answer identically.\n- `409` `AGENT_PROCESSING` — A run is in progress (status `processing`); the agent cannot be changed until it settles. Retry once it is `active` or `paused`.\n- `422` `VALIDATION_FAILED` — The request failed this endpoint's own validation — `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      }
    },
    "/business/agents/{agentId}/activate": {
      "post": {
        "operationId": "activateAgent",
        "summary": "Start a draft agent (spends credits)",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned.",
            "schema": {
              "type": "string",
              "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned."
            }
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "config",
                        "isReconstructed",
                        "lossyFields",
                        "sourceLists"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "web-monitor",
                            "person-starting-new-job",
                            "linkedin-posts",
                            "person-discovery-via-filters",
                            "job-postings",
                            "job-posting-in-location",
                            "first-person-hired-in-company-department",
                            "first-person-hired-internationally",
                            "company-headcount-growth",
                            "company-headcount-growth-over-baseline",
                            "company-department-headcount",
                            "company-employee-job-location-in-two-countries",
                            "funding-announcements",
                            "people-watcher",
                            "companies-watcher",
                            "job-changes-watcher",
                            "linkedin-profile",
                            "linkedin-post",
                            null
                          ],
                          "description": "The public agent kind — the same slug you POST to at /business/agents/{type}. null for a legacy kind this API no longer offers."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, which is also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active",
                            "paused",
                            "expired",
                            "failed",
                            "completed",
                            "deleted"
                          ],
                          "description": "initializing = saved draft, nothing billed; processing = a run is under way; active = running; paused = stopped by you; expired = past its expirationDate; failed = the provider setup failed. Older agents can also read `completed` (a one-off scrape that has finished) and `deleted` (an agent deleted before deletions were timestamped: still readable, but it can no longer be edited or activated)."
                        },
                        "config": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The agent's config in CREATE shape: exactly the body you would POST to /business/agents/{type} (without `start`) to build this agent again. Its fields are the ones documented on that type's create operation."
                        },
                        "isReconstructed": {
                          "type": "boolean",
                          "description": "false = the config is the stored snapshot, returned verbatim (always the case for a draft). true = the agent was started before its snapshot existed and the config was rebuilt from the live record, so check `lossyFields`."
                        },
                        "lossyFields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Config fields that could not be recovered when `isReconstructed` is true; `[\"*\"]` means only `name` is known. Empty otherwise."
                        },
                        "sourceLists": {
                          "type": "array",
                          "description": "Watcher kinds only: the source lists the config names, resolved to their names. Empty for every other kind.",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "name"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "The source list's id."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The source list's name, or null when the list has been deleted."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce4e65fd738c00d8927a",
                    "type": "web-monitor",
                    "name": "Regulator fines 2026",
                    "status": "processing",
                    "config": {
                      "listName": "Regulator fines 2026",
                      "entityType": "company",
                      "prompt": "companies fined by a financial regulator in 2026",
                      "searchPeriod": "6h",
                      "numResults": 7
                    },
                    "isReconstructed": false,
                    "lossyFields": [],
                    "sourceLists": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Starts a DRAFT agent and SPENDS CREDITS. It creates the agent's results list, checks and deducts the balance, sets up the provider subscriptions and kicks off the first run; the agent moves through `processing` to `active` (a scrape stays `processing` until the scrape finishes). Only drafts can be activated: there is no resume in this API, so a started, paused, expired or failed agent answers 409 AGENT_NOT_A_DRAFT — to restart a paused agent, duplicate it and activate the copy. Nothing is created or spent when the draft's `expirationDate` is not in the future (422 VALIDATION_FAILED), its name is already taken (409 LIST_NAME_TAKEN) or the balance is short (402 INSUFFICIENT_CREDITS). Any OTHER reason a config cannot be started (a source list with nothing to watch, a plan limit, a field the type's schema refuses) is not classified at activation time and answers 500 UNEXPECTED_ERROR: create the agent with `start: true` instead, which reports those properly. Answers 202 with the agent as GET returns it; keep polling GET /business/agents/{agentId} until `status` settles.\n\nErrors:\n- `404` `AGENT_NOT_FOUND` — No agent with this id belongs to the token owner. A deleted agent and another user's agent answer identically.\n- `409` `AGENT_NOT_A_DRAFT` — The agent is not a draft (status is not `initializing`): it was already started, or is paused, expired or failed. Only drafts are editable and activatable — duplicate the agent and work on the copy.\n- `409` `LIST_NAME_TAKEN` — `listName` is already used by one of your lists or agents. Pick another name.\n- `402` `INSUFFICIENT_CREDITS` — The workspace does not have enough credits to start this agent. Nothing was created or spent.\n- `409` `AGENT_CONFIG_MISSING` — The draft carries no stored config to work from (a legacy draft saved before configs were persisted). Create the agent again.\n- `409` `AGENT_TYPE_UNSUPPORTED` — The agent is of a legacy kind this API can no longer edit or activate; its `type` reads as null.\n- `422` `VALIDATION_FAILED` — The activation was rejected by validation: the draft's `expirationDate` is not in the future (fix it with PATCH, or duplicate the agent and set a new date), or the request itself failed this endpoint's validation (`agentId` must be a 24-character hex id). No other config problem is reported here: see the 500 entry.\n- `422` `AGENT_SIGNAL_REJECTED` — web-monitor only: the search provider refused the `prompt` as a searchable signal. Rewrite the prompt rather than retrying it.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. A config the activation cannot accept for any reason other than the expiry rule (a source list with nothing to watch, a plan limit, a field the type's schema refuses) also lands here, because the agents service does not classify those at activation time. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      }
    },
    "/business/agents/{agentId}/stop": {
      "post": {
        "operationId": "pauseAgent",
        "summary": "Pause an agent (one-way, there is no resume)",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned.",
            "schema": {
              "type": "string",
              "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "config",
                        "isReconstructed",
                        "lossyFields",
                        "sourceLists"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "web-monitor",
                            "person-starting-new-job",
                            "linkedin-posts",
                            "person-discovery-via-filters",
                            "job-postings",
                            "job-posting-in-location",
                            "first-person-hired-in-company-department",
                            "first-person-hired-internationally",
                            "company-headcount-growth",
                            "company-headcount-growth-over-baseline",
                            "company-department-headcount",
                            "company-employee-job-location-in-two-countries",
                            "funding-announcements",
                            "people-watcher",
                            "companies-watcher",
                            "job-changes-watcher",
                            "linkedin-profile",
                            "linkedin-post",
                            null
                          ],
                          "description": "The public agent kind — the same slug you POST to at /business/agents/{type}. null for a legacy kind this API no longer offers."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, which is also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active",
                            "paused",
                            "expired",
                            "failed",
                            "completed",
                            "deleted"
                          ],
                          "description": "initializing = saved draft, nothing billed; processing = a run is under way; active = running; paused = stopped by you; expired = past its expirationDate; failed = the provider setup failed. Older agents can also read `completed` (a one-off scrape that has finished) and `deleted` (an agent deleted before deletions were timestamped: still readable, but it can no longer be edited or activated)."
                        },
                        "config": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The agent's config in CREATE shape: exactly the body you would POST to /business/agents/{type} (without `start`) to build this agent again. Its fields are the ones documented on that type's create operation."
                        },
                        "isReconstructed": {
                          "type": "boolean",
                          "description": "false = the config is the stored snapshot, returned verbatim (always the case for a draft). true = the agent was started before its snapshot existed and the config was rebuilt from the live record, so check `lossyFields`."
                        },
                        "lossyFields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Config fields that could not be recovered when `isReconstructed` is true; `[\"*\"]` means only `name` is known. Empty otherwise."
                        },
                        "sourceLists": {
                          "type": "array",
                          "description": "Watcher kinds only: the source lists the config names, resolved to their names. Empty for every other kind.",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "name"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "The source list's id."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The source list's name, or null when the list has been deleted."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8d7a5032fd74700391356b",
                    "type": "companies-watcher",
                    "name": "Fundraising Sofiia 25 aug",
                    "status": "paused",
                    "config": {
                      "listName": "Fundraising Sofiia 25 aug",
                      "eventType": "company-watch-funding-milestones",
                      "listIds": [
                        "6a7ef6d7d1d092349bbf5db5"
                      ],
                      "expirationDate": "2026-08-26",
                      "frequency": 1,
                      "maxContacts": 50
                    },
                    "isReconstructed": true,
                    "lossyFields": [],
                    "sourceLists": [
                      {
                        "id": "6a7ef6d7d1d092349bbf5db5",
                        "name": "tegna_44 - Companies"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Pauses a running agent: its provider subscriptions (for a scrape, its recurring schedule) stop, `status` becomes `paused`, and no further results are delivered or billed. Already-delivered rows stay in the results list. This is one-way through the API: `activate` only accepts drafts, so a paused agent cannot be resumed here; duplicate it and activate the copy instead. A draft has nothing to pause and is refused with 409 AGENT_NOT_RUNNING (pausing one would strand it: activate takes drafts only). An agent that has already expired can still be paused and answers 200. Answers 200 with the agent as GET returns it.\n\nErrors:\n- `404` `AGENT_NOT_FOUND` — No agent with this id belongs to the token owner. A deleted agent and another user's agent answer identically.\n- `409` `AGENT_NOT_RUNNING` — The agent has nothing to pause: it is still a draft (`initializing`), or its provider subscription is already gone. Drafts are refused deliberately, because a paused draft could never be started again (activate accepts drafts only).\n- `422` `VALIDATION_FAILED` — The request failed this endpoint's own validation — `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      }
    },
    "/business/agents/{agentId}/duplicate": {
      "post": {
        "operationId": "duplicateAgent",
        "summary": "Copy an agent as a fresh draft",
        "tags": [
          "Agents"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "agentId",
            "in": "path",
            "required": true,
            "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned.",
            "schema": {
              "type": "string",
              "description": "The agent's id: a 24-character hex string — the `id` of an item from GET /business/agents, or the `agent.id` a create or duplicate returned."
            }
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "agent"
                  ],
                  "properties": {
                    "agent": {
                      "type": "object",
                      "required": [
                        "id",
                        "type",
                        "name",
                        "status",
                        "config",
                        "isReconstructed",
                        "lossyFields",
                        "sourceLists"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "The agent's id — pass it as `{agentId}` to every other agent operation."
                        },
                        "type": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "web-monitor",
                            "person-starting-new-job",
                            "linkedin-posts",
                            "person-discovery-via-filters",
                            "job-postings",
                            "job-posting-in-location",
                            "first-person-hired-in-company-department",
                            "first-person-hired-internationally",
                            "company-headcount-growth",
                            "company-headcount-growth-over-baseline",
                            "company-department-headcount",
                            "company-employee-job-location-in-two-countries",
                            "funding-announcements",
                            "people-watcher",
                            "companies-watcher",
                            "job-changes-watcher",
                            "linkedin-profile",
                            "linkedin-post",
                            null
                          ],
                          "description": "The public agent kind — the same slug you POST to at /business/agents/{type}. null for a legacy kind this API no longer offers."
                        },
                        "name": {
                          "type": "string",
                          "description": "The agent's name, which is also the name of the results list it delivers into."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "initializing",
                            "processing",
                            "active",
                            "paused",
                            "expired",
                            "failed",
                            "completed",
                            "deleted"
                          ],
                          "description": "initializing = saved draft, nothing billed; processing = a run is under way; active = running; paused = stopped by you; expired = past its expirationDate; failed = the provider setup failed. Older agents can also read `completed` (a one-off scrape that has finished) and `deleted` (an agent deleted before deletions were timestamped: still readable, but it can no longer be edited or activated)."
                        },
                        "config": {
                          "type": "object",
                          "additionalProperties": true,
                          "description": "The agent's config in CREATE shape: exactly the body you would POST to /business/agents/{type} (without `start`) to build this agent again. Its fields are the ones documented on that type's create operation."
                        },
                        "isReconstructed": {
                          "type": "boolean",
                          "description": "false = the config is the stored snapshot, returned verbatim (always the case for a draft). true = the agent was started before its snapshot existed and the config was rebuilt from the live record, so check `lossyFields`."
                        },
                        "lossyFields": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Config fields that could not be recovered when `isReconstructed` is true; `[\"*\"]` means only `name` is known. Empty otherwise."
                        },
                        "sourceLists": {
                          "type": "array",
                          "description": "Watcher kinds only: the source lists the config names, resolved to their names. Empty for every other kind.",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "name"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "The source list's id."
                              },
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "The source list's name, or null when the list has been deleted."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "agent": {
                    "id": "6a8dce6665fd738c00d8928a",
                    "type": "web-monitor",
                    "name": "Regulator fines 2026 (Copy)",
                    "status": "initializing",
                    "config": {
                      "listName": "Regulator fines 2026 (Copy)",
                      "entityType": "company",
                      "prompt": "companies fined by a financial regulator in 2026",
                      "searchPeriod": "6h",
                      "numResults": 7
                    },
                    "isReconstructed": false,
                    "lossyFields": [],
                    "sourceLists": []
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Copies an agent of any status into a NEW draft named \"<source name> (Copy)\" (`status: initializing`, nothing billed). A draft source copies losslessly. A source that was started before configs were snapshotted is rebuilt from its live record, and every field that could not be recovered is listed in `lossyFields` — set those with PATCH before you activate the copy. This is also how you restart a paused agent, since `activate` only accepts drafts. The copy counts towards the free plan's 10-agent cap (403 AGENT_LIMIT_REACHED). Answers 201 with the new draft in the same shape as GET; activate it with POST /business/agents/{agentId}/activate using the returned `id`.\n\nErrors:\n- `404` `AGENT_NOT_FOUND` — No agent with this id belongs to the token owner. A deleted agent and another user's agent answer identically.\n- `403` `AGENT_LIMIT_REACHED` — Free-plan accounts may hold at most 10 agents, drafts included. Delete an agent or upgrade the plan.\n- `422` `VALIDATION_FAILED` — The request failed this endpoint's own validation — `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — The agents bucket is exhausted: 30 requests per minute or 2,000 per day per token owner, shared by every /business/agents operation (a 429 raised by the agents service is relayed with this code too). Retry after the `Retry-After` header.\n- `500` `UNEXPECTED_ERROR` — The agents service failed (5xx, refused service credential, or a timeout after 60s) or the rate limiter was unavailable. Retry later; quote `request_id` to support.\n\nRequires one of the following token scopes: agents."
      }
    },
    "/business/research/providers": {
      "get": {
        "operationId": "listResearchProviders",
        "summary": "The research providers a run can use",
        "tags": [
          "Research"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "providers": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "business-data",
                              "company-lookalike-data",
                              "company-signals",
                              "contact-email-and-phone-enrichment",
                              "contact-verification",
                              "social-and-ad-intelligence",
                              "web-search"
                            ]
                          },
                          "description": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "iconUrl": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "docsUrl": {
                            "type": "string"
                          },
                          "keyMode": {
                            "type": "string",
                            "enum": [
                              "platform",
                              "byok",
                              "byok-required"
                            ]
                          },
                          "hasUserKey": {
                            "type": "boolean"
                          },
                          "allowedInRuns": {
                            "type": "boolean"
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "platform",
                              "byok",
                              "none"
                            ]
                          },
                          "enrichment": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "channels": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "enum": [
                                    "work_email",
                                    "personal_email",
                                    "phone"
                                  ]
                                }
                              },
                              "inputs": {
                                "type": "object",
                                "properties": {
                                  "anyOf": {
                                    "type": "array",
                                    "items": {
                                      "type": "array",
                                      "items": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                },
                                "required": [
                                  "anyOf"
                                ]
                              },
                              "keyMode": {
                                "type": "string",
                                "enum": [
                                  "platform",
                                  "byok",
                                  "byok-required"
                                ]
                              }
                            },
                            "required": [
                              "channels",
                              "inputs",
                              "keyMode"
                            ]
                          }
                        },
                        "required": [
                          "id",
                          "label",
                          "category",
                          "description",
                          "iconUrl",
                          "docsUrl",
                          "keyMode",
                          "hasUserKey",
                          "allowedInRuns",
                          "source",
                          "enrichment"
                        ]
                      }
                    }
                  },
                  "required": [
                    "providers"
                  ]
                },
                "example": {
                  "providers": [
                    {
                      "id": "apollo",
                      "label": "Apollo",
                      "category": "contact-email-and-phone-enrichment",
                      "description": "People & company search with contact info; people match/enrich.",
                      "iconUrl": "https://www.google.com/s2/favicons?sz=128&domain=apollo.io",
                      "docsUrl": "https://tryfuse.ai/providers/apollo",
                      "keyMode": "byok-required",
                      "hasUserKey": false,
                      "allowedInRuns": true,
                      "source": "none",
                      "enrichment": {
                        "channels": [
                          "work_email",
                          "personal_email",
                          "phone"
                        ],
                        "inputs": {
                          "anyOf": [
                            [
                              "linkedin_url"
                            ],
                            [
                              "first_name",
                              "last_name",
                              "company_name"
                            ],
                            [
                              "first_name",
                              "last_name",
                              "domain"
                            ]
                          ]
                        },
                        "keyMode": "platform"
                      }
                    },
                    {
                      "id": "zerobounce",
                      "label": "ZeroBounce",
                      "category": "contact-verification",
                      "description": "Verify/validate email deliverability.",
                      "iconUrl": "https://www.google.com/s2/favicons?sz=128&domain=zerobounce.net",
                      "docsUrl": "https://tryfuse.ai/providers/zerobounce",
                      "keyMode": "platform",
                      "hasUserKey": false,
                      "allowedInRuns": true,
                      "source": "platform",
                      "enrichment": null
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The Deep Research provider catalog for the token owner: every provider's id (slug), label, category, description, icon and docs link, its key mode (platform: it runs on Fuse's key; byok-required: the user must save their own key), whether this user has saved one (hasUserKey), where the key that would be used comes from (source: platform, byok or none), whether research runs may call it (allowedInRuns) and, when the provider can back an enrichment waterfall, the channels it fills and the input-field combinations it accepts. Keys are never returned. The catalog informs BYOK settings and smart-column provider choice; a run itself has no provider selector. Rate limit: 30 requests per minute, 1000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: research."
      }
    },
    "/business/research/runs": {
      "post": {
        "operationId": "startResearchRun",
        "summary": "Start a Deep Research run",
        "tags": [
          "Research"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "run": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "queued",
                            "planning",
                            "plan_review",
                            "running",
                            "generating_csv",
                            "uploading",
                            "completed",
                            "failed",
                            "cancelled"
                          ]
                        }
                      },
                      "required": [
                        "runId",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "run"
                  ]
                },
                "example": {
                  "run": {
                    "runId": "68a205cc9c41d20014b40888",
                    "status": "queued"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Starts an autonomous Deep Research run for the prompt and returns immediately with 202. Billing is per provider action inside the run, gated by the balance and capped by `effort` (low 1000, medium 2000 (default), high 5000 credits); the run always produces a markdown report (`reportMarkdown` on GET /business/research/runs/{runId}) and, when it surfaces people or companies, a result list (`resultListId`). Send an `X-Idempotency-Key` header of 8 to 200 characters to make retries safe: a replay returns the existing run instead of starting another (a key outside that length is rejected with 422; an empty header is treated as if none was sent). Poll GET /business/research/runs/{runId} until status is completed, failed or cancelled, or stream progress from GET /business/research/runs/{runId}/events. Prompts are limited to 2000 characters by the research engine. Rate limits: 30 requests per minute and 1000 per day on this endpoint, plus 5 run starts per minute and 100 per day in the research engine.\n\nErrors:\n- `422` `VALIDATION_FAILED` — `prompt` is missing or outside 4-2000 characters, `effort` is not low, medium or high, or the `X-Idempotency-Key` header was sent with a value outside 8-200 characters.\n- `429` `RATE_LIMITED` — Either this endpoint's quota (30 per minute, 1000 per day) or the research engine's own start quota (5 per minute, 100 per day) is exhausted; retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: research.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "minLength": 4,
                    "maxLength": 2000,
                    "description": "The research question or brief in plain text, 4 to 2000 characters."
                  },
                  "effort": {
                    "type": "string",
                    "enum": [
                      "low",
                      "medium",
                      "high"
                    ],
                    "description": "Research depth tier that sets the run's credit spend cap: low (1000 credits), medium (2000, the default when omitted) or high (5000)."
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listResearchRuns",
        "summary": "Research runs currently in flight",
        "tags": [
          "Research"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "runId": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "prompt": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "queued",
                              "planning",
                              "plan_review",
                              "running",
                              "generating_csv",
                              "uploading",
                              null
                            ]
                          },
                          "turnCount": {
                            "type": "integer"
                          },
                          "createdAt": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "updatedAt": {
                            "type": [
                              "string",
                              "null"
                            ]
                          }
                        },
                        "required": [
                          "runId",
                          "prompt",
                          "status",
                          "turnCount",
                          "createdAt",
                          "updatedAt"
                        ]
                      }
                    }
                  },
                  "required": [
                    "runs"
                  ]
                },
                "example": {
                  "runs": [
                    {
                      "runId": "68a205cc9c41d20014b40888",
                      "prompt": "Series A fintech companies in Europe hiring a Head of Sales",
                      "status": "running",
                      "turnCount": 7,
                      "createdAt": "2026-08-25T10:00:00.000Z",
                      "updatedAt": "2026-08-25T10:03:12.000Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The token owner's research runs still in flight (status queued, planning, plan_review, running, generating_csv or uploading), newest first, capped at 50. Finished runs are not listed — read them individually with GET /business/research/runs/{runId}. `prompt` is the text the run was started with and `turnCount` how many research turns it has taken so far. Rate limit: 30 requests per minute, 1000 per day.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: research."
      }
    },
    "/business/research/runs/{runId}": {
      "get": {
        "operationId": "getResearchRun",
        "summary": "A research run's state, report, and result list",
        "tags": [
          "Research"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "The research run id (24-character hex), as returned in `run.runId` by POST /business/research/runs.",
            "schema": {
              "type": "string",
              "description": "The research run id (24-character hex), as returned in `run.runId` by POST /business/research/runs."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "run": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "prompt": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "status": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "queued",
                            "planning",
                            "plan_review",
                            "running",
                            "generating_csv",
                            "uploading",
                            "completed",
                            "failed",
                            "cancelled",
                            null
                          ]
                        },
                        "turnCount": {
                          "type": "integer"
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "effort": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "low",
                            "medium",
                            "high",
                            null
                          ]
                        },
                        "spend": {
                          "type": "object",
                          "properties": {
                            "reservedCredits": {
                              "type": "integer"
                            },
                            "settledCredits": {
                              "type": "integer"
                            },
                            "capCredits": {
                              "type": "integer"
                            }
                          },
                          "required": [
                            "reservedCredits",
                            "settledCredits",
                            "capCredits"
                          ]
                        },
                        "resultListId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "reportMarkdown": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "errorCode": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "ORCHESTRATOR_ERROR",
                            "ENGINE_MISCONFIGURED",
                            "HARNESS_NO_OUTPUT",
                            "STALE_TIMEOUT",
                            "SANDBOX_POOL_TIMEOUT",
                            null
                          ]
                        },
                        "cancelRequestedAt": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      },
                      "required": [
                        "runId",
                        "prompt",
                        "status",
                        "turnCount",
                        "createdAt",
                        "updatedAt",
                        "effort",
                        "spend",
                        "resultListId",
                        "reportMarkdown",
                        "errorCode",
                        "cancelRequestedAt"
                      ]
                    }
                  },
                  "required": [
                    "run"
                  ]
                },
                "example": {
                  "run": {
                    "runId": "68a205cc9c41d20014b40888",
                    "prompt": "Series A fintech companies in Europe hiring a Head of Sales",
                    "status": "completed",
                    "turnCount": 14,
                    "createdAt": "2026-08-25T10:00:00.000Z",
                    "updatedAt": "2026-08-25T10:11:48.000Z",
                    "effort": "medium",
                    "spend": {
                      "reservedCredits": 0,
                      "settledCredits": 890,
                      "capCredits": 2000
                    },
                    "resultListId": "68a205cc9c41d20014b40999",
                    "reportMarkdown": "# European fintech Series A\n\n12 companies matched. Highlights:\n\n- **Northwind Pay** raised a $14M Series A in June and posted a Head of Sales role in Berlin.\n",
                    "errorCode": null,
                    "cancelRequestedAt": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "A research run's full state. Poll it until `status` is completed, failed or cancelled (in-flight statuses: queued, planning, plan_review, running, generating_csv, uploading). `prompt` is the text the run was started with; `spend` shows the credits reserved, settled and the cap `effort` set; `reportMarkdown` is the markdown report (null until the run writes it); `resultListId` is the list holding the people or companies the research surfaced (null when none was created), readable with GET /business/lists/{listId}; `errorCode` explains a failed run and `cancelRequestedAt` is set once a cancel has been accepted. Rate limit: 30 requests per minute, 1000 per day.\n\nErrors:\n- `404` `RESEARCH_RUN_NOT_FOUND` — No research run with that id belongs to the token owner.\n- `422` `VALIDATION_FAILED` — `runId` is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: research."
      }
    },
    "/business/research/runs/{runId}/events": {
      "get": {
        "operationId": "listResearchRunEvents",
        "summary": "A research run's progress events",
        "tags": [
          "Research"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "The research run id (24-character hex), as returned in `run.runId` by POST /business/research/runs.",
            "schema": {
              "type": "string",
              "description": "The research run id (24-character hex), as returned in `run.runId` by POST /business/research/runs."
            }
          },
          {
            "name": "sinceSeq",
            "in": "query",
            "required": false,
            "description": "Return only events whose `seq` is strictly greater than this value; pass the last `seq` you received (or `nextSinceSeq`) to poll incrementally, omit it for the first page.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "description": "Return only events whose `seq` is strictly greater than this value; pass the last `seq` you received (or `nextSinceSeq`) to poll incrementally, omit it for the first page."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of events per page, 1 to 500 (default 100); when a page comes back full, `nextSinceSeq` carries the last `seq` to continue from.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "description": "Maximum number of events per page, 1 to 500 (default 100); when a page comes back full, `nextSinceSeq` carries the last `seq` to continue from."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "runId": {
                      "type": "string"
                    },
                    "events": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "seq": {
                            "type": "integer"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "run.status_changed",
                              "plan.created",
                              "tool.started",
                              "tool.finished",
                              "progress",
                              "partial_result",
                              "artifact",
                              "run.completed",
                              "run.failed",
                              "run.cancelled"
                            ]
                          },
                          "payload": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "ts": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "seq",
                          "type",
                          "payload",
                          "ts"
                        ]
                      }
                    },
                    "nextSinceSeq": {
                      "type": [
                        "integer",
                        "null"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "planning",
                        "plan_review",
                        "running",
                        "generating_csv",
                        "uploading",
                        "completed",
                        "failed",
                        "cancelled"
                      ]
                    }
                  },
                  "required": [
                    "runId",
                    "events",
                    "nextSinceSeq",
                    "status"
                  ]
                },
                "example": {
                  "runId": "68a205cc9c41d20014b40888",
                  "events": [
                    {
                      "seq": 3,
                      "type": "run.status_changed",
                      "payload": {
                        "from": "planning",
                        "to": "running"
                      },
                      "ts": "2026-08-25T10:00:41.000Z"
                    },
                    {
                      "seq": 4,
                      "type": "tool.started",
                      "payload": {
                        "tool": "web_search",
                        "input": {
                          "query": "European fintech Series A 2026 Head of Sales"
                        }
                      },
                      "ts": "2026-08-25T10:01:05.000Z"
                    },
                    {
                      "seq": 5,
                      "type": "progress",
                      "payload": {
                        "message": "Reviewing 18 candidate companies"
                      },
                      "ts": "2026-08-25T10:02:10.000Z"
                    }
                  ],
                  "nextSinceSeq": null,
                  "status": "running"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The run's progress log in ascending `seq` order (the durable source of truth for what the agent did). Poll with `sinceSeq` set to the last `seq` you have seen: only newer events come back. A full page sets `nextSinceSeq` to its last seq (pass it as the next `sinceSeq`); otherwise it is null and you are caught up. `status` is the run's current status so a poller can stop when it is completed, failed or cancelled. Event types: run.status_changed, plan.created, tool.started, tool.finished, progress, partial_result, artifact, run.completed, run.failed, run.cancelled; `payload` depends on the type. Rate limit: 30 requests per minute, 1000 per day.\n\nErrors:\n- `404` `RESEARCH_RUN_NOT_FOUND` — No research run with that id belongs to the token owner.\n- `422` `VALIDATION_FAILED` — `runId` is not a 24-character hex id, `sinceSeq` is not an integer of 0 or more, or `limit` is outside 1-500.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: research."
      }
    },
    "/business/research/runs/{runId}/cancel": {
      "post": {
        "operationId": "cancelResearchRun",
        "summary": "Cancel an in-flight research run",
        "tags": [
          "Research"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "description": "The research run id (24-character hex), as returned in `run.runId` by POST /business/research/runs.",
            "schema": {
              "type": "string",
              "description": "The research run id (24-character hex), as returned in `run.runId` by POST /business/research/runs."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "run": {
                      "type": "object",
                      "properties": {
                        "runId": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "queued",
                            "planning",
                            "plan_review",
                            "running",
                            "generating_csv",
                            "uploading",
                            "completed",
                            "failed",
                            "cancelled"
                          ]
                        }
                      },
                      "required": [
                        "runId",
                        "status"
                      ]
                    }
                  },
                  "required": [
                    "run"
                  ]
                },
                "example": {
                  "run": {
                    "runId": "68a205cc9c41d20014b40888",
                    "status": "cancelled"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Requests cancellation of an in-flight run and returns its new status (cancelled). Credits already settled for provider actions are not refunded; reserved credits are released. A run that has already finished (completed, failed or cancelled) cannot be cancelled and answers 409. Rate limit: 30 requests per minute, 1000 per day.\n\nErrors:\n- `404` `RESEARCH_RUN_NOT_FOUND` — No research run with that id belongs to the token owner.\n- `409` `RUN_ALREADY_TERMINAL` — The run has already finished (completed, failed or cancelled) and cannot be cancelled.\n- `422` `VALIDATION_FAILED` — `runId` is not a 24-character hex id.\n- `429` `RATE_LIMITED` — Per-user quota for this endpoint family exceeded (30 per minute, 1000 per day); retry after the Retry-After / RateLimit-Reset seconds.\n\nRequires one of the following token scopes: research."
      }
    },
    "/business/companies/filter-options": {
      "get": {
        "operationId": "getCompanyFilterOptions",
        "summary": "Get the accepted company-search filter values",
        "tags": [
          "Company search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "filterOptions"
                  ],
                  "properties": {
                    "filterOptions": {
                      "type": "object",
                      "required": [
                        "fiberIndustries",
                        "crunchbaseIndustries",
                        "crunchbaseCategoryGroups",
                        "linkedinIndustries",
                        "companyTags",
                        "naicsCodes",
                        "countries",
                        "accelerators"
                      ],
                      "properties": {
                        "fiberIndustries": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Values for the `industriesV2` filter."
                        },
                        "crunchbaseIndustries": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Values for the `crunchbaseCategories` filter."
                        },
                        "crunchbaseCategoryGroups": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Values for the `crunchbaseCategoryGroups` filter; case-sensitive."
                        },
                        "linkedinIndustries": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Values for the `linkedinIndustries` filter."
                        },
                        "companyTags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Values for the `tags` filter."
                        },
                        "naicsCodes": {
                          "type": "array",
                          "description": "Send `code` as the `naicsCodes` filter value.",
                          "items": {
                            "type": "object",
                            "required": [
                              "code",
                              "title"
                            ],
                            "properties": {
                              "code": {
                                "type": "string"
                              },
                              "title": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "countries": {
                          "type": "array",
                          "description": "Send `apiCode` as the `headquartersCountryCode` and `officeLocationsV2` filter value.",
                          "items": {
                            "type": "object",
                            "required": [
                              "name",
                              "apiCode",
                              "isoCodeAlpha2",
                              "flag"
                            ],
                            "properties": {
                              "name": {
                                "type": "string"
                              },
                              "apiCode": {
                                "type": "string",
                                "description": "3-letter code, e.g. USA."
                              },
                              "isoCodeAlpha2": {
                                "type": "string"
                              },
                              "flag": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "accelerators": {
                          "type": "array",
                          "description": "Send `acceleratorSlug` as the `acceleratorsV2` filter value.",
                          "items": {
                            "type": "object",
                            "required": [
                              "acceleratorSlug",
                              "acceleratorName",
                              "numCompanies"
                            ],
                            "properties": {
                              "acceleratorSlug": {
                                "type": "string"
                              },
                              "acceleratorName": {
                                "type": "string"
                              },
                              "numCompanies": {
                                "type": "integer",
                                "description": "How many companies in the index carry this accelerator."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "filterOptions": {
                    "fiberIndustries": [
                      "Administrative Services",
                      "Aerospace & Military",
                      "Artificial Intelligence",
                      "Finance",
                      "Software",
                      "Travel & Tourism"
                    ],
                    "crunchbaseIndustries": [
                      "3D Printing",
                      "3D Technology",
                      "A/B Testing",
                      "Financial Services"
                    ],
                    "crunchbaseCategoryGroups": [
                      "Administrative Services",
                      "Advertising",
                      "Agriculture and Farming",
                      "Apps",
                      "Financial Services"
                    ],
                    "linkedinIndustries": [
                      "3D Printing",
                      "Abrasives and Nonmetallic Minerals Manufacturing",
                      "Software Development"
                    ],
                    "companyTags": [
                      "raised-from-top-vc",
                      "is-government",
                      "is-school",
                      "venture-backed-startup"
                    ],
                    "naicsCodes": [
                      {
                        "code": "11",
                        "title": "Agriculture, Forestry, Fishing and Hunting"
                      },
                      {
                        "code": "111110",
                        "title": "Soybean Farming"
                      },
                      {
                        "code": "513210",
                        "title": "Software Publishers"
                      }
                    ],
                    "countries": [
                      {
                        "name": "United States of America",
                        "apiCode": "USA",
                        "isoCodeAlpha2": "US",
                        "flag": "🇺🇸"
                      },
                      {
                        "name": "United Kingdom",
                        "apiCode": "GBR",
                        "isoCodeAlpha2": "GB",
                        "flag": "🇬🇧"
                      }
                    ],
                    "accelerators": [
                      {
                        "acceleratorSlug": "ycombinator",
                        "acceleratorName": "Y Combinator",
                        "numCompanies": 6219
                      },
                      {
                        "acceleratorSlug": "techstars",
                        "acceleratorName": "Techstars",
                        "numCompanies": 5612
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The accepted values for every enum-backed company filter, each list trimmed to exactly what a filter takes. Use `fiberIndustries` for `industriesV2`, `linkedinIndustries` for `linkedinIndustries`, `crunchbaseIndustries` for `crunchbaseCategories`, `crunchbaseCategoryGroups` for `crunchbaseCategoryGroups` (case-sensitive — copy them verbatim), `companyTags` for `tags`, `naicsCodes[].code` for `naicsCodes`, `countries[].apiCode` for both `headquartersCountryCode` and `officeLocationsV2`, and `accelerators[].acceleratorSlug` for `acceleratorsV2`. Filters with no enumerable vocabulary are documented on the request schema instead: `status` (active / acquired / closed), `stage` (pre_seed, seed, series_a…series_j, public, acquired, closed, private_equity, venture_other, no_funding_yet, unknown), `fortuneRankings` (fortune-500 / fortune-1000) and `technologies`; company names, investor domains and `headquartersCity` place names come from GET /companies/autocomplete. Static vocabulary: no tenant data and no credits.\n\nErrors:\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: companies."
      }
    },
    "/business/companies/autocomplete": {
      "get": {
        "operationId": "autocompleteCompanySearchField",
        "summary": "Suggest values for company and location filters",
        "tags": [
          "Company search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "field",
            "in": "query",
            "required": true,
            "description": "`company` suggests company names (each with its `domain` when known); `location` suggests fully qualified place names (e.g. Dallas, Texas, United States) to send as `headquartersCity` values.",
            "schema": {
              "type": "string",
              "enum": [
                "company",
                "location"
              ],
              "description": "`company` suggests company names (each with its `domain` when known); `location` suggests fully qualified place names (e.g. Dallas, Texas, United States) to send as `headquartersCity` values."
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Text fragment to complete (2-200 chars).",
            "schema": {
              "type": "string",
              "minLength": 2,
              "maxLength": 200,
              "description": "Text fragment to complete (2-200 chars)."
            }
          },
          {
            "name": "orgType",
            "in": "query",
            "required": false,
            "description": "`investor` narrows `field=company` to investors, for the `investors` filter; not allowed with `field=location`.",
            "schema": {
              "type": "string",
              "enum": [
                "investor"
              ],
              "description": "`investor` narrows `field=company` to investors, for the `investors` filter; not allowed with `field=location`."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "field",
                    "suggestions"
                  ],
                  "properties": {
                    "field": {
                      "type": "string",
                      "enum": [
                        "company",
                        "location"
                      ],
                      "description": "Echo of the requested field."
                    },
                    "suggestions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "name"
                        ],
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "For `field=company` the company name; for `field=location` the fully qualified place name to send as a `headquartersCity` value."
                          },
                          "domain": {
                            "type": "string",
                            "description": "`field=company` only, and only when the provider has one."
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "field": "company",
                  "suggestions": [
                    {
                      "name": "BrightPay",
                      "domain": "brightpay.in"
                    },
                    {
                      "name": "BrightPay"
                    },
                    {
                      "name": "BrightPay Health Corp.",
                      "domain": "brightpay.org"
                    },
                    {
                      "name": "BrightPay Technologies Ltd."
                    },
                    {
                      "name": "BRIGHT PAYROLL LIMITED",
                      "domain": "brightstarpayroll.co.uk"
                    },
                    {
                      "name": "BRIGHT PAY LIMITED"
                    },
                    {
                      "name": "Bright Payroll Solutions Limited",
                      "domain": "brightps.co.uk"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Resolves free-text input to canonical company-filter values; two characters minimum. `field=company` returns company names with their `domain` when known — send `name` to `nameLike`, or `domain` to `domains`; add `orgType=investor` to search investors instead, whose `domain` is the value the `investors` filter takes. `field=location` returns fully qualified place names (\"Dallas, Texas, United States\") which are exactly what the `headquartersCity` filter takes — the qualification is what lets the geocoder tell six same-named cities apart, so send the whole string. Note that `officeLocationsV2` is a different filter and takes country `apiCode`s from GET /companies/filter-options, not these place names. Same vocabulary as the product's type-ahead; free.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: companies."
      }
    },
    "/business/companies/search": {
      "post": {
        "operationId": "searchCompanies",
        "summary": "Run a company search",
        "tags": [
          "Company search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "companies",
                    "total",
                    "nextCursor",
                    "filters"
                  ],
                  "properties": {
                    "companies": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "required": [
                          "isSaved"
                        ],
                        "properties": {
                          "isSaved": {
                            "type": "boolean",
                            "description": "Whether this company is already in one of your company lists."
                          },
                          "preferred_name": {
                            "type": "string"
                          },
                          "names": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "domains": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "linkedin_primary_slug": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "standard_industries": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "naics_codes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "status_consensus": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "funding_stage": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "employee_count_consensus": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "gte": {
                                "type": "integer"
                              },
                              "lte": {
                                "type": "integer"
                              }
                            }
                          },
                          "location_consensus": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "total": {
                      "type": [
                        "integer",
                        "null"
                      ],
                      "description": "True match count on the first page; null on every cursor page, where the upstream does not count."
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Send back as `cursor` with the same filter source for the next page; null on the last page."
                    },
                    "filters": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The RESOLVED filters the search actually ran."
                    },
                    "unresolvedCriteria": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Only when the source was `query`: criteria in the prose that could not be turned into a filter."
                    }
                  }
                },
                "example": {
                  "companies": [
                    {
                      "preferred_name": "Airbnb",
                      "names": [
                        "AirBed & Breakfast",
                        "Airbnb, Inc.",
                        "Airbnb",
                        "Airbnb Inc"
                      ],
                      "domains": [
                        "airbnb.com",
                        "abnb.me",
                        "airbnb.ca",
                        "airbnb.co.in",
                        "airbnb.com.br",
                        "airbnb.co.uk",
                        "airbnb.fr",
                        "airbnb.it",
                        "airbnb.nl"
                      ],
                      "websites": [
                        "airbnb.com"
                      ],
                      "linkedin_primary_slug": "airbnb",
                      "linkedin_slugs": [
                        "airbnb"
                      ],
                      "linkedin_id": "309694",
                      "li_description": "Airbnb was born in 2007 when two hosts welcomed three guests to their San Francisco home, and has since grown to over 5 million hosts who have welcomed over 2 billion guest arrivals in almost every country across the globe. Every day, hosts offer unique stays, experiences and services that make it possible for guests to connect with communities in a more authentic way.",
                      "li_follower_count": 3115489,
                      "li_industries": [
                        {
                          "id": "4",
                          "name": "Software Development"
                        }
                      ],
                      "standard_industries": [
                        "Retail",
                        "Real Estate",
                        "Hospitality",
                        "Software",
                        "Travel & Tourism"
                      ],
                      "naics_codes": [
                        "513210",
                        "721110"
                      ],
                      "tags": [
                        "raised-from-top-vc"
                      ],
                      "status_consensus": "active",
                      "funding_stage": "public",
                      "founded_on_consensus": "2008-08-11T00:00:00.000Z",
                      "employee_count_consensus": {
                        "gte": 72716,
                        "lte": 72716
                      },
                      "revenue_estimate": {
                        "sources": [
                          "https://bullfincher.io/companies/airbnb/revenue",
                          "https://www.macrotrends.net/stocks/charts/ABNB/airbnb/revenue",
                          "https://stockanalysis.com/quote/bvl/ABNB/revenue/",
                          "https://sqmagazine.co.uk/airbnb-statistics/",
                          "http://www.wallstreetzen.com/stocks/us/nasdaq/abnb/revenue",
                          "https://www.statista.com/topics/2273/airbnb/",
                          "https://stockanalysis.com/stocks/abnb/revenue/",
                          "https://news.airbnb.com/airbnb-q4-2025-financial-results/",
                          "https://www.sec.gov/Archives/edgar/data/1559720/000119312526048670/d58192dex991.htm"
                        ],
                        "fiscal_year": 2025,
                        "value_usd": {
                          "gte": 12241000000,
                          "lte": 12241000000
                        }
                      },
                      "total_funding_consensus": 8935132065,
                      "location_consensus": {
                        "street_address": "888 Brannan Street",
                        "neighborhood": null,
                        "city": "San Francisco",
                        "state_name": "California",
                        "state_code": "CA",
                        "county": null,
                        "postal_code": "94103",
                        "country_code": "USA",
                        "country_name": "United States of America",
                        "coordinates": {
                          "lat": 37.779238,
                          "lon": -122.419359
                        },
                        "timezone": null,
                        "full_address": "San Francisco, California, United States of America",
                        "formatted_address": "San Francisco, California, United States of America"
                      },
                      "location_name": "San Francisco, California, United States of America",
                      "logo_url": "https://api.fiber.ai/v1/company-logo/at_bomkrvppqn1pssoqsxqy.jpeg",
                      "short_description": "Airbnb is an online community marketplace for people to list, discover, and book accommodations through mobile phones or the Internet.",
                      "technologies_used": [
                        {
                          "name": "slack"
                        }
                      ],
                      "is_investor": true,
                      "relevance_score": 12.987053,
                      "isSaved": true
                    }
                  ],
                  "total": 438741,
                  "nextCursor": "gAAAAABqjeNDAAd1qTVJYeUYtzhveDm-GOvYXgomDWX2a6V4OvEFB44biu_7SGszYsdcHjezHmxytwVmoiTf4P5VcPuiv4nFQQuCs4ZvsJu17hJ2n1tiR_w=",
                  "filters": {
                    "status": [
                      {
                        "label": "Active",
                        "value": "active",
                        "status": "include"
                      }
                    ],
                    "industriesV2": [
                      {
                        "label": "Travel & Tourism",
                        "value": "Travel & Tourism",
                        "status": "include"
                      },
                      {
                        "label": "Artificial Intelligence",
                        "value": "Artificial Intelligence",
                        "status": "exclude"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The company twin of the people search. The filter source is exactly one of: literal `filters`, a stored COMPANY saved search (`savedSearchId` / `savedSearchName`), or a natural-language `query` (converted into filters server-side; criteria it could not map come back as `unresolvedCriteria`). A people saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH.\n\nThe response always echoes the RESOLVED `filters`. Page by re-sending the same filter source together with the returned `nextCursor` as `cursor`; `nextCursor` is null on the last page. `total` is the true match count and is only counted on the FIRST page — every cursor page answers `total: null`, so read the count once and carry it.\n\nRows are the provider's company record (snake_case, ~80 fields, varying by company: names, domains, LinkedIn metadata, industries, NAICS codes, headcount and revenue estimates, funding, technologies, headquarters location) plus Fuse's `isSaved`, which says whether the company is already in one of your company lists.\n\n`filters.headquartersCity` names are geocoded one by one and the resulting city areas are OR-ed together; a name that geocodes to nothing is dropped and the search runs on the rest, so take the values from GET /companies/autocomplete?field=location. Only when not one name resolves is the search refused with 422 CITY_FILTER_UNRESOLVED. `employeeCountV2` is the one range whose lower bound is exclusive: `{ min: 50 }` matches companies with more than 50 employees.\n\nBilling: 2 credits per requested company are pre-checked and 2 credits per company returned are debited.\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — The balance does not cover the pre-check for this request; nothing was billed.\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id or exact title.\n- `409` `SAVED_SEARCH_NAME_AMBIGUOUS` — Two of your saved searches share that title — reference it by `savedSearchId` instead.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `422` `SAVED_SEARCH_TYPE_MISMATCH` — The saved search exists but stores the other kind of filters; `param` is `savedSearchId`.\n- `422` `SAVED_SEARCH_INVALID` — The STORED filters no longer form a runnable company search — the blob is empty, or every value in it was retired. A filterless stored search is refused here rather than run as a whole-universe search.\n- `422` `QUERY_FILTERS_INVALID` — The natural-language `query` produced no usable filter; name concrete criteria.\n- `422` `CITY_FILTER_UNRESOLVED` — NOT ONE of the `filters.headquartersCity` names geocoded to a city area, so the search was refused rather than run worldwide; names that do geocode are OR-ed together and a name that does not is dropped, so this fires only when every name fails. `param` is `filters.headquartersCity`.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: companies.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "properties": {
                      "nameLike": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "maxLength": 500
                        },
                        "description": "Free text: company-name fragments of at most 500 chars each, matched fuzzily against the company NAME only (never the description). Several fragments are OR-joined (provider `nameLike.anyOf`); resolve a real company to its canonical name with GET /companies/autocomplete?field=company."
                      },
                      "domains": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Free text: company website domains (e.g. stripe.com). A scheme, a www. prefix, a path and the letter case are all stripped before the search, so https://www.Stripe.com/pricing and stripe.com behave the same; a value that is not a domain at all is dropped. Several domains are OR-joined."
                      },
                      "keywords": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Free-text keywords matched against company names and descriptions; any may match."
                      },
                      "status": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Operating-status entries whose `value` is one of exactly: active, acquired, closed. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`). The provider ignores an exclude list on this field, so an exclusion is sent as the statuses that were NOT excluded, which also drops companies whose status is unknown. This filter ANDs with the others."
                      },
                      "tags": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Company-tag entries whose `value` is a slug from `companyTags` in GET /companies/filter-options: raised-from-top-vc, venture-backed-startup, is-government, is-school. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "industriesV2": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Industry entries whose `value` is one of the `fiberIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software, Finance). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "linkedinIndustries": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "LinkedIn-industry entries whose `value` is one of the `linkedinIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software Development) — a much finer taxonomy than `industriesV2`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "crunchbaseCategories": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Crunchbase-category entries whose `value` is one of the `crunchbaseIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Financial Services). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "crunchbaseCategoryGroups": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Crunchbase category groups as plain strings copied verbatim (case-sensitive) from `crunchbaseCategoryGroups` in GET /companies/filter-options (e.g. Financial Services) — the broad parent of `crunchbaseCategories`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Several groups are OR-joined (provider `anyOf`); this filter has no exclude form."
                      },
                      "naicsCodes": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "NAICS entries whose `value` is the code, not the title (`naicsCodes[].code` in GET /companies/filter-options, e.g. 513210 for Software Publishers; 2- to 6-digit codes are all accepted, a shorter code being the broader sector). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "headquartersCountryCode": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Headquarters-country entries whose `value` is the country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA, DEU). The two-letter `isoCodeAlpha2` in the same row (US, DE) is NOT accepted — the provider rejects it and the whole search fails. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "headquartersStateName": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Headquarters state/province entries whose `value` is the full state or province name (e.g. Florida, California)."
                      },
                      "headquartersCity": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "maxItems": 25,
                        "description": "Up to 25 fully qualified place names from GET /companies/autocomplete?field=location (e.g. Dallas, Texas, United States); each is geocoded independently to its city bounds and the areas are OR-ed together (no exclusion). A name that geocodes to nothing is dropped and the search runs on the names that did resolve — take the values from the typeahead so every one of them counts — and only when NOT ONE of them resolves is the search refused rather than run worldwide (422 CITY_FILTER_UNRESOLVED)."
                      },
                      "employeeCountV2": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Headcount range `{ min?, max? }`; any whole number is taken on either side and is used as sent — the values the search UI offers (1, 10, 50, 200, 500, 1000, 5000, 10000) are its own vocabulary, not a constraint here. The lower bound is EXCLUSIVE and the upper bound inclusive, so `{ min: 50 }` matches companies with MORE than 50 employees, and `{ min: 300, max: 320 }` matches 301 to 320. Inverted bounds are read the other way round, and an equal pair keeps only the lower bound, because the provider rejects a range whose bounds meet."
                      },
                      "revenueUSD": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Estimated annual revenue range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                      },
                      "totalFundingUSD": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Total funding raised range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                      },
                      "lastFundingUSD": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Size range of the most recent funding round `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                      },
                      "stage": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Funding-stage entries whose `value` is one of exactly: pre_seed, seed, series_a, series_b, series_c, series_d, series_e, series_f, series_g, series_h, series_i, series_j, public, acquired, closed, private_equity, venture_other, no_funding_yet, unknown. No endpoint serves this list — it is fixed here. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "technologies": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Technology-in-use entries whose `value` is a name from the provider's predefined technology vocabulary, forwarded verbatim, so it must carry the product's own spelling and casing — e.g. Salesforce, Kubernetes, Next.js, Google Analytics, and `AWS` for Amazon Web Services. No endpoint serves this vocabulary yet; the product's own picker offers a curated 141-name subset. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "investors": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Investor entries whose `value` is the investor's website domain — resolve names with GET /companies/autocomplete?field=company&orgType=investor and send the `domain` from that response, never the investor's name. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "foundedOn": {
                        "type": "object",
                        "properties": {
                          "start": {
                            "type": "string",
                            "description": "Earliest date, ISO-8601 (e.g. 2020-01-01)."
                          },
                          "end": {
                            "type": "string",
                            "description": "Latest date, ISO-8601 (e.g. 2024-12-31)."
                          }
                        },
                        "description": "Founding-date range `{ start?, end? }` as ISO-8601 dates."
                      },
                      "lastFundedOn": {
                        "type": "object",
                        "properties": {
                          "start": {
                            "type": "string",
                            "description": "Earliest date, ISO-8601 (e.g. 2020-01-01)."
                          },
                          "end": {
                            "type": "string",
                            "description": "Latest date, ISO-8601 (e.g. 2024-12-31)."
                          }
                        },
                        "description": "Date range of the most recent funding round, `{ start?, end? }` as ISO-8601 dates."
                      },
                      "acceleratorsV2": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Accelerator entries whose `value` is the `acceleratorSlug` from `accelerators` in GET /companies/filter-options (e.g. ycombinator, techstars); the `acceleratorName` in the same row is NOT accepted. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "fortuneRankings": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Fortune-list entries whose `value` is one of exactly: fortune-500, fortune-1000 (fortune-1000 contains fortune-500). Any other value is silently DROPPED and the whole filter disappears, so the search then runs with no ranking constraint at all rather than returning nothing. Include values are OR-joined (provider `anyOf`). The provider takes an include list only here, and the tiers nest, so an exclude value cannot be honoured and is ignored. This filter ANDs with the others."
                      },
                      "officeLocationsV2": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Office-location entries whose `value` is a country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA) — the same vocabulary as `headquartersCountryCode`, but matching ANY office rather than only the headquarters. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "linkedinSlugs": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Free text: LinkedIn company slugs (e.g. stripe). A full company URL is accepted and reduced to the part after linkedin.com/company/, and the value is lower-cased, because the provider matches the slug exactly. Several slugs are OR-joined."
                      }
                    },
                    "description": "Literal filters, one of the four filter sources. Company filters in the search vocabulary: include/exclude fields take `[{ status, value, label }]` entries (`label` is required), list fields arrays of strings, ranges `{ min, max }` and date ranges `{ start, end }` — enum vocabularies come from GET /companies/filter-options, names and places from GET /companies/autocomplete. Must contain at least one non-empty value."
                  },
                  "savedSearchId": {
                    "type": "string",
                    "description": "Id of one of your COMPANY saved searches to take the filters from instead of `filters` (a people saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH)."
                  },
                  "savedSearchName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Exact title of one of your company saved searches to take the filters from instead of `filters`; two searches sharing the title answer 409 SAVED_SEARCH_NAME_AMBIGUOUS."
                  },
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Natural-language description of the companies to find (max 2000 chars), converted into filters server-side instead of `filters`; criteria that could not be mapped come back as `unresolvedCriteria`, and a query yielding no filter answers 422 QUERY_FILTERS_INVALID."
                  },
                  "size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 25,
                    "description": "Companies per page (1-100, default 25); the search pre-checks 2 credits per requested company and debits 2 credits per company returned."
                  },
                  "cursor": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "The `nextCursor` returned by the previous page, sent together with the same filter source; null (default) starts from the first page. The match `total` is only counted on the first page — it comes back null on every cursor page."
                  }
                },
                "description": "Exactly one filter source — `filters`, `savedSearchId`, `savedSearchName` or `query` — plus optional paging."
              }
            }
          }
        }
      }
    },
    "/business/companies/search/save-to-list": {
      "post": {
        "operationId": "saveCompanySearchToList",
        "summary": "Save company-search results into a list",
        "tags": [
          "Company search"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "listIds"
                  ],
                  "properties": {
                    "listIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The single destination company list id the save is writing into.",
                      "minItems": 1,
                      "maxItems": 1
                    }
                  }
                },
                "example": {
                  "listIds": [
                    "6a8d82b5c5017e82fb6082ac"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Run the search server-side and save up to `limit` matches into a company list. Same filter-source contract as POST /companies/search — exactly one of `filters`, `savedSearchId`, `savedSearchName` or `query`. The destination is exactly one of `listId` or `listName`; `listName` is create-or-reuse by exact name (case-insensitive), a name shared by two lists is a 409, and system list names are refused.\n\n`filters.headquartersCity` names are geocoded one by one and OR-ed together; a name that geocodes to nothing is dropped and the job runs on the rest — only when not one resolves is it refused with 422 CITY_FILTER_UNRESOLVED, and there is no upfront credit pre-check, so take the values from GET /companies/autocomplete?field=location. Fiber firmographics land on the saved companies automatically — there is no `enrich` switch. Always async: 202 means the save started, not that the list is populated; poll the list's rows. Billing: the job saves in pages of 100 and debits 2 credits per company as it goes, so there is no upfront pre-check and a partially completed run is partially billed.\n\nErrors:\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id or exact title.\n- `409` `SAVED_SEARCH_NAME_AMBIGUOUS` — Two of your saved searches share that title — reference it by `savedSearchId` instead.\n- `409` `LIST_NAME_AMBIGUOUS` — Two of your company lists share that name — pass `listId` instead.\n- `409` `LIST_NAME_TAKEN` — A company list with that name was created concurrently; retry with `listId`.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `422` `SAVED_SEARCH_TYPE_MISMATCH` — The saved search exists but stores the other kind of filters; `param` is `savedSearchId`.\n- `422` `SAVED_SEARCH_INVALID` — The STORED filters no longer form a runnable company search — the blob is empty, or every value in it was retired. A filterless stored search is refused here rather than saved from a whole-universe search.\n- `422` `QUERY_FILTERS_INVALID` — The natural-language `query` produced no usable filter; name concrete criteria.\n- `422` `CITY_FILTER_UNRESOLVED` — NOT ONE of the `filters.headquartersCity` names geocoded to a city area, so the save was refused before it started; names that do geocode are OR-ed together and a name that does not is dropped, so this fires only when every name fails. `param` is `filters.headquartersCity`.\n- `422` `LIST_NAME_RESERVED` — `listName` is a system/dynamic list title and cannot be a destination.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: companies.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "filters": {
                    "type": "object",
                    "properties": {
                      "nameLike": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "maxLength": 500
                        },
                        "description": "Free text: company-name fragments of at most 500 chars each, matched fuzzily against the company NAME only (never the description). Several fragments are OR-joined (provider `nameLike.anyOf`); resolve a real company to its canonical name with GET /companies/autocomplete?field=company."
                      },
                      "domains": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Free text: company website domains (e.g. stripe.com). A scheme, a www. prefix, a path and the letter case are all stripped before the search, so https://www.Stripe.com/pricing and stripe.com behave the same; a value that is not a domain at all is dropped. Several domains are OR-joined."
                      },
                      "keywords": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Free-text keywords matched against company names and descriptions; any may match."
                      },
                      "status": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Operating-status entries whose `value` is one of exactly: active, acquired, closed. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`). The provider ignores an exclude list on this field, so an exclusion is sent as the statuses that were NOT excluded, which also drops companies whose status is unknown. This filter ANDs with the others."
                      },
                      "tags": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Company-tag entries whose `value` is a slug from `companyTags` in GET /companies/filter-options: raised-from-top-vc, venture-backed-startup, is-government, is-school. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "industriesV2": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Industry entries whose `value` is one of the `fiberIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software, Finance). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "linkedinIndustries": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "LinkedIn-industry entries whose `value` is one of the `linkedinIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software Development) — a much finer taxonomy than `industriesV2`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "crunchbaseCategories": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Crunchbase-category entries whose `value` is one of the `crunchbaseIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Financial Services). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "crunchbaseCategoryGroups": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Crunchbase category groups as plain strings copied verbatim (case-sensitive) from `crunchbaseCategoryGroups` in GET /companies/filter-options (e.g. Financial Services) — the broad parent of `crunchbaseCategories`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Several groups are OR-joined (provider `anyOf`); this filter has no exclude form."
                      },
                      "naicsCodes": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "NAICS entries whose `value` is the code, not the title (`naicsCodes[].code` in GET /companies/filter-options, e.g. 513210 for Software Publishers; 2- to 6-digit codes are all accepted, a shorter code being the broader sector). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "headquartersCountryCode": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Headquarters-country entries whose `value` is the country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA, DEU). The two-letter `isoCodeAlpha2` in the same row (US, DE) is NOT accepted — the provider rejects it and the whole search fails. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "headquartersStateName": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Headquarters state/province entries whose `value` is the full state or province name (e.g. Florida, California)."
                      },
                      "headquartersCity": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "maxItems": 25,
                        "description": "Up to 25 fully qualified place names from GET /companies/autocomplete?field=location (e.g. Dallas, Texas, United States); each is geocoded independently to its city bounds and the areas are OR-ed together (no exclusion). A name that geocodes to nothing is dropped and the search runs on the names that did resolve — take the values from the typeahead so every one of them counts — and only when NOT ONE of them resolves is the search refused rather than run worldwide (422 CITY_FILTER_UNRESOLVED)."
                      },
                      "employeeCountV2": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Headcount range `{ min?, max? }`; any whole number is taken on either side and is used as sent — the values the search UI offers (1, 10, 50, 200, 500, 1000, 5000, 10000) are its own vocabulary, not a constraint here. The lower bound is EXCLUSIVE and the upper bound inclusive, so `{ min: 50 }` matches companies with MORE than 50 employees, and `{ min: 300, max: 320 }` matches 301 to 320. Inverted bounds are read the other way round, and an equal pair keeps only the lower bound, because the provider rejects a range whose bounds meet."
                      },
                      "revenueUSD": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Estimated annual revenue range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                      },
                      "totalFundingUSD": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Total funding raised range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                      },
                      "lastFundingUSD": {
                        "type": "object",
                        "properties": {
                          "min": {
                            "type": "number",
                            "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                          },
                          "max": {
                            "type": "number",
                            "description": "Inclusive upper bound."
                          }
                        },
                        "description": "Size range of the most recent funding round `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                      },
                      "stage": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Funding-stage entries whose `value` is one of exactly: pre_seed, seed, series_a, series_b, series_c, series_d, series_e, series_f, series_g, series_h, series_i, series_j, public, acquired, closed, private_equity, venture_other, no_funding_yet, unknown. No endpoint serves this list — it is fixed here. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "technologies": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Technology-in-use entries whose `value` is a name from the provider's predefined technology vocabulary, forwarded verbatim, so it must carry the product's own spelling and casing — e.g. Salesforce, Kubernetes, Next.js, Google Analytics, and `AWS` for Amazon Web Services. No endpoint serves this vocabulary yet; the product's own picker offers a curated 141-name subset. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "investors": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Investor entries whose `value` is the investor's website domain — resolve names with GET /companies/autocomplete?field=company&orgType=investor and send the `domain` from that response, never the investor's name. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "foundedOn": {
                        "type": "object",
                        "properties": {
                          "start": {
                            "type": "string",
                            "description": "Earliest date, ISO-8601 (e.g. 2020-01-01)."
                          },
                          "end": {
                            "type": "string",
                            "description": "Latest date, ISO-8601 (e.g. 2024-12-31)."
                          }
                        },
                        "description": "Founding-date range `{ start?, end? }` as ISO-8601 dates."
                      },
                      "lastFundedOn": {
                        "type": "object",
                        "properties": {
                          "start": {
                            "type": "string",
                            "description": "Earliest date, ISO-8601 (e.g. 2020-01-01)."
                          },
                          "end": {
                            "type": "string",
                            "description": "Latest date, ISO-8601 (e.g. 2024-12-31)."
                          }
                        },
                        "description": "Date range of the most recent funding round, `{ start?, end? }` as ISO-8601 dates."
                      },
                      "acceleratorsV2": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Accelerator entries whose `value` is the `acceleratorSlug` from `accelerators` in GET /companies/filter-options (e.g. ycombinator, techstars); the `acceleratorName` in the same row is NOT accepted. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "fortuneRankings": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Fortune-list entries whose `value` is one of exactly: fortune-500, fortune-1000 (fortune-1000 contains fortune-500). Any other value is silently DROPPED and the whole filter disappears, so the search then runs with no ranking constraint at all rather than returning nothing. Include values are OR-joined (provider `anyOf`). The provider takes an include list only here, and the tiers nest, so an exclude value cannot be honoured and is ignored. This filter ANDs with the others."
                      },
                      "officeLocationsV2": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "value": {
                              "type": "string",
                              "description": "The filter value — see the field's own description for its vocabulary."
                            },
                            "label": {
                              "type": "string",
                              "description": "Display label for the value (required; repeat the value when you have no label)."
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "include",
                                "exclude"
                              ],
                              "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                            }
                          },
                          "required": [
                            "value",
                            "label",
                            "status"
                          ]
                        },
                        "description": "Office-location entries whose `value` is a country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA) — the same vocabulary as `headquartersCountryCode`, but matching ANY office rather than only the headquarters. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                      },
                      "linkedinSlugs": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        },
                        "description": "Free text: LinkedIn company slugs (e.g. stripe). A full company URL is accepted and reduced to the part after linkedin.com/company/, and the value is lower-cased, because the provider matches the slug exactly. Several slugs are OR-joined."
                      }
                    },
                    "description": "Literal filters, one of the four filter sources — the same vocabulary as POST /companies/search. Company filters in the search vocabulary: include/exclude fields take `[{ status, value, label }]` entries (`label` is required), list fields arrays of strings, ranges `{ min, max }` and date ranges `{ start, end }` — enum vocabularies come from GET /companies/filter-options, names and places from GET /companies/autocomplete. Must contain at least one non-empty value."
                  },
                  "savedSearchId": {
                    "type": "string",
                    "description": "Id of one of your COMPANY saved searches to take the filters from instead of `filters` (a people saved search answers 422 SAVED_SEARCH_TYPE_MISMATCH)."
                  },
                  "savedSearchName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Exact title of one of your company saved searches to take the filters from instead of `filters`; two searches sharing the title answer 409 SAVED_SEARCH_NAME_AMBIGUOUS."
                  },
                  "query": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Natural-language description of the companies to find (max 2000 chars), converted into filters server-side instead of `filters`; criteria that could not be mapped come back as `unresolvedCriteria`, and a query yielding no filter answers 422 QUERY_FILTERS_INVALID."
                  },
                  "limit": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 10000,
                    "description": "Maximum number of matching companies to save (1-10000); the background job saves in pages of 100 and debits 2 credits per company saved as it goes (no upfront credit check)."
                  },
                  "listId": {
                    "type": "string",
                    "description": "Id of an existing company list to save into (exactly one of `listId` / `listName`)."
                  },
                  "listName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Name of the destination company list, created when none exists; an existing list with the same name (case-insensitive) is reused, a name shared by several lists answers 409 LIST_NAME_AMBIGUOUS, and system list names answer 422 LIST_NAME_RESERVED."
                  }
                },
                "required": [
                  "limit"
                ],
                "description": "Exactly one filter source (`filters` | `savedSearchId` | `savedSearchName` | `query`) and exactly one destination (`listId` | `listName`), plus `limit`."
              }
            }
          }
        }
      }
    },
    "/business/saved-searches": {
      "get": {
        "operationId": "listSavedSearches",
        "summary": "List the token owner's saved searches",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Restrict the listing to one kind, `people` or `company`; omitted returns both.",
            "schema": {
              "type": "string",
              "enum": [
                "people",
                "company"
              ],
              "description": "Restrict the listing to one kind, `people` or `company`; omitted returns both."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "savedSearches"
                  ],
                  "properties": {
                    "savedSearches": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "title",
                          "filters",
                          "ignoredFilterKeys",
                          "searchType",
                          "createdAt",
                          "updatedAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "filters": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "additionalProperties": true,
                            "description": "Filters in the vocabulary of `searchType`; null only when a stored people blob could not be translated at all."
                          },
                          "ignoredFilterKeys": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Stored keys with no equivalent search field, dropped from `filters` (always empty for company searches)."
                          },
                          "searchType": {
                            "type": "string",
                            "enum": [
                              "people",
                              "company"
                            ]
                          },
                          "createdAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "savedSearches": [
                    {
                      "id": "6a8d82c6305c048277b9e535",
                      "title": "ss25aug",
                      "createdAt": "2026-08-25T11:55:50.968Z",
                      "updatedAt": "2026-08-25T11:55:50.968Z",
                      "filters": {
                        "status": [
                          {
                            "label": "Active",
                            "value": "active",
                            "status": "include"
                          }
                        ],
                        "industriesV2": [
                          {
                            "label": "Travel & Tourism",
                            "value": "Travel & Tourism",
                            "status": "include"
                          },
                          {
                            "label": "Artificial Intelligence",
                            "value": "Artificial Intelligence",
                            "status": "exclude"
                          }
                        ]
                      },
                      "ignoredFilterKeys": [],
                      "searchType": "company"
                    },
                    {
                      "id": "6a8d75e85eb3d2ad77913e36",
                      "title": "ss25aug",
                      "createdAt": "2026-08-25T11:00:56.030Z",
                      "updatedAt": "2026-08-25T11:00:56.030Z",
                      "filters": {
                        "job_company_name": [
                          {
                            "status": "include",
                            "value": "costar group"
                          }
                        ],
                        "job_title_role": [
                          {
                            "status": "include",
                            "value": "engineering"
                          }
                        ],
                        "job_title_sub_role": [
                          {
                            "status": "include",
                            "value": "software"
                          }
                        ]
                      },
                      "ignoredFilterKeys": [],
                      "searchType": "people"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Every saved search the token owner has, people and company alike, newest-updated first; `?type=people|company` narrows to one kind. The listing is complete — there is no paging.\n\n`filters` is reported in the language the matching search endpoint accepts (POST /prospects/search for `people`, POST /companies/search for `company`), so a listed search can be re-run or edited without a translation step: pass the row's `id` as `savedSearchId`, or send its `filters` back verbatim. `ignoredFilterKeys` names stored keys that have no equivalent search field and were dropped from `filters`; the product's own UI skips them too, so a run matches what the app shows.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search."
      },
      "post": {
        "operationId": "createSavedSearch",
        "summary": "Create a saved search",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "savedSearch"
                  ],
                  "properties": {
                    "savedSearch": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "filters",
                        "ignoredFilterKeys",
                        "searchType",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "filters": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": true,
                          "description": "Filters in the vocabulary of `searchType`; null only when a stored people blob could not be translated at all."
                        },
                        "ignoredFilterKeys": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Stored keys with no equivalent search field, dropped from `filters` (always empty for company searches)."
                        },
                        "searchType": {
                          "type": "string",
                          "enum": [
                            "people",
                            "company"
                          ]
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "savedSearch": {
                    "id": "6a8de3161ea5e58766c32c88",
                    "title": "CoStar Group CXOs (US)",
                    "createdAt": "2026-08-25T18:46:46.159Z",
                    "updatedAt": "2026-08-25T18:46:46.159Z",
                    "filters": {
                      "job_title_levels": [
                        {
                          "status": "include",
                          "value": "cxo"
                        }
                      ],
                      "location_country": [
                        {
                          "status": "include",
                          "value": "united states"
                        }
                      ],
                      "job_company_name": [
                        {
                          "status": "include",
                          "value": "costar group"
                        }
                      ]
                    },
                    "ignoredFilterKeys": [],
                    "searchType": "people"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Store a search under a name. `type` picks the kind — `people` (the default) or `company` — and decides which language `filters` must speak: people filters are the keys POST /prospects/search takes, company filters the keys POST /companies/search takes. Either way the search opens identically in the product UI, and the created row comes back with its filters in that same search vocabulary, ready to re-send.\n\nExactly two of the 46 people filter fields cannot round-trip through the product's filter rail — `first_name` and `last_name` — and are rejected with 422 SAVED_SEARCH_FILTERS_UNSUPPORTED naming the field, rather than stored in a form the app cannot reopen. Every other field stores, `work_email`, `mobile_phone`, `personal_emails`, `linkedin_url`, `github_url` and `facebook_url` included. `type` is immutable: PATCH can change the title and the filters, never the kind. Titles need not be unique, but a title shared by two searches can no longer be used as `savedSearchName`.\n\nErrors:\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `422` `SAVED_SEARCH_FILTERS_UNSUPPORTED` — `filters` names `first_name` or `last_name` — the only two people filter fields with no saved-search equivalent; `param` names the field.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Display name of the saved search (1-255 chars); need not be unique, but a shared title cannot be referenced as `savedSearchName` later."
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "people",
                      "company"
                    ],
                    "default": "people",
                    "description": "Kind of search the filters describe: `people` (default) or `company`; immutable after creation."
                  },
                  "filters": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "nameLike": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "maxLength": 500
                            },
                            "description": "Free text: company-name fragments of at most 500 chars each, matched fuzzily against the company NAME only (never the description). Several fragments are OR-joined (provider `nameLike.anyOf`); resolve a real company to its canonical name with GET /companies/autocomplete?field=company."
                          },
                          "domains": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Free text: company website domains (e.g. stripe.com). A scheme, a www. prefix, a path and the letter case are all stripped before the search, so https://www.Stripe.com/pricing and stripe.com behave the same; a value that is not a domain at all is dropped. Several domains are OR-joined."
                          },
                          "keywords": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Free-text keywords matched against company names and descriptions; any may match."
                          },
                          "status": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Operating-status entries whose `value` is one of exactly: active, acquired, closed. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`). The provider ignores an exclude list on this field, so an exclusion is sent as the statuses that were NOT excluded, which also drops companies whose status is unknown. This filter ANDs with the others."
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Company-tag entries whose `value` is a slug from `companyTags` in GET /companies/filter-options: raised-from-top-vc, venture-backed-startup, is-government, is-school. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "industriesV2": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Industry entries whose `value` is one of the `fiberIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software, Finance). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "linkedinIndustries": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "LinkedIn-industry entries whose `value` is one of the `linkedinIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Software Development) — a much finer taxonomy than `industriesV2`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "crunchbaseCategories": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Crunchbase-category entries whose `value` is one of the `crunchbaseIndustries` values in GET /companies/filter-options, copied exactly as listed (e.g. Financial Services). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "crunchbaseCategoryGroups": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Crunchbase category groups as plain strings copied verbatim (case-sensitive) from `crunchbaseCategoryGroups` in GET /companies/filter-options (e.g. Financial Services) — the broad parent of `crunchbaseCategories`. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Several groups are OR-joined (provider `anyOf`); this filter has no exclude form."
                          },
                          "naicsCodes": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "NAICS entries whose `value` is the code, not the title (`naicsCodes[].code` in GET /companies/filter-options, e.g. 513210 for Software Publishers; 2- to 6-digit codes are all accepted, a shorter code being the broader sector). An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "headquartersCountryCode": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Headquarters-country entries whose `value` is the country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA, DEU). The two-letter `isoCodeAlpha2` in the same row (US, DE) is NOT accepted — the provider rejects it and the whole search fails. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "headquartersStateName": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Headquarters state/province entries whose `value` is the full state or province name (e.g. Florida, California)."
                          },
                          "headquartersCity": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 200
                            },
                            "maxItems": 25,
                            "description": "Up to 25 fully qualified place names from GET /companies/autocomplete?field=location (e.g. Dallas, Texas, United States); each is geocoded independently to its city bounds and the areas are OR-ed together (no exclusion). A name that geocodes to nothing is dropped and the search runs on the names that did resolve — take the values from the typeahead so every one of them counts — and only when NOT ONE of them resolves is the search refused rather than run worldwide (422 CITY_FILTER_UNRESOLVED)."
                          },
                          "employeeCountV2": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Headcount range `{ min?, max? }`; any whole number is taken on either side and is used as sent — the values the search UI offers (1, 10, 50, 200, 500, 1000, 5000, 10000) are its own vocabulary, not a constraint here. The lower bound is EXCLUSIVE and the upper bound inclusive, so `{ min: 50 }` matches companies with MORE than 50 employees, and `{ min: 300, max: 320 }` matches 301 to 320. Inverted bounds are read the other way round, and an equal pair keeps only the lower bound, because the provider rejects a range whose bounds meet."
                          },
                          "revenueUSD": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Estimated annual revenue range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                          },
                          "totalFundingUSD": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Total funding raised range `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                          },
                          "lastFundingUSD": {
                            "type": "object",
                            "properties": {
                              "min": {
                                "type": "number",
                                "description": "Lower bound, inclusive — except on `employeeCountV2`, whose lower bound is exclusive (see that field)."
                              },
                              "max": {
                                "type": "number",
                                "description": "Inclusive upper bound."
                              }
                            },
                            "description": "Size range of the most recent funding round `{ min?, max? }`; the accepted values are whole US dollars, not millions (5000000 means $5M), and both bounds are inclusive."
                          },
                          "stage": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Funding-stage entries whose `value` is one of exactly: pre_seed, seed, series_a, series_b, series_c, series_d, series_e, series_f, series_g, series_h, series_i, series_j, public, acquired, closed, private_equity, venture_other, no_funding_yet, unknown. No endpoint serves this list — it is fixed here. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "technologies": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Technology-in-use entries whose `value` is a name from the provider's predefined technology vocabulary, forwarded verbatim, so it must carry the product's own spelling and casing — e.g. Salesforce, Kubernetes, Next.js, Google Analytics, and `AWS` for Amazon Web Services. No endpoint serves this vocabulary yet; the product's own picker offers a curated 141-name subset. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "investors": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Investor entries whose `value` is the investor's website domain — resolve names with GET /companies/autocomplete?field=company&orgType=investor and send the `domain` from that response, never the investor's name. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "foundedOn": {
                            "type": "object",
                            "properties": {
                              "start": {
                                "type": "string",
                                "description": "Earliest date, ISO-8601 (e.g. 2020-01-01)."
                              },
                              "end": {
                                "type": "string",
                                "description": "Latest date, ISO-8601 (e.g. 2024-12-31)."
                              }
                            },
                            "description": "Founding-date range `{ start?, end? }` as ISO-8601 dates."
                          },
                          "lastFundedOn": {
                            "type": "object",
                            "properties": {
                              "start": {
                                "type": "string",
                                "description": "Earliest date, ISO-8601 (e.g. 2020-01-01)."
                              },
                              "end": {
                                "type": "string",
                                "description": "Latest date, ISO-8601 (e.g. 2024-12-31)."
                              }
                            },
                            "description": "Date range of the most recent funding round, `{ start?, end? }` as ISO-8601 dates."
                          },
                          "acceleratorsV2": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Accelerator entries whose `value` is the `acceleratorSlug` from `accelerators` in GET /companies/filter-options (e.g. ycombinator, techstars); the `acceleratorName` in the same row is NOT accepted. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "fortuneRankings": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Fortune-list entries whose `value` is one of exactly: fortune-500, fortune-1000 (fortune-1000 contains fortune-500). Any other value is silently DROPPED and the whole filter disappears, so the search then runs with no ranking constraint at all rather than returning nothing. Include values are OR-joined (provider `anyOf`). The provider takes an include list only here, and the tiers nest, so an exclude value cannot be honoured and is ignored. This filter ANDs with the others."
                          },
                          "officeLocationsV2": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "value": {
                                  "type": "string",
                                  "description": "The filter value — see the field's own description for its vocabulary."
                                },
                                "label": {
                                  "type": "string",
                                  "description": "Display label for the value (required; repeat the value when you have no label)."
                                },
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes companies carrying it (includes OR together, every exclude applies)."
                                }
                              },
                              "required": [
                                "value",
                                "label",
                                "status"
                              ]
                            },
                            "description": "Office-location entries whose `value` is a country's three-letter `apiCode` from `countries` in GET /companies/filter-options (e.g. USA) — the same vocabulary as `headquartersCountryCode`, but matching ANY office rather than only the headquarters. An off-list value is not rejected by this API: the search comes back empty (or fails upstream) with no error naming the field, so check the value against the list first. Include values are OR-joined (provider `anyOf`) and every exclude value is removed (`noneOf`); this filter ANDs with the others."
                          },
                          "linkedinSlugs": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Free text: LinkedIn company slugs (e.g. stripe). A full company URL is accepted and reduced to the part after linkedin.com/company/, and the value is lower-cased, because the provider matches the slug exactly. Several slugs are OR-joined."
                          }
                        },
                        "description": "Company filters in the search vocabulary: include/exclude fields take `[{ status, value, label }]` entries (`label` is required), list fields arrays of strings, ranges `{ min, max }` and date ranges `{ start, end }` — enum vocabularies come from GET /companies/filter-options, names and places from GET /companies/autocomplete. Must contain at least one non-empty value."
                      },
                      {
                        "type": "object",
                        "properties": {
                          "industry": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Industry of the person themselves; include/exclude entries whose `value` is one of the 147 `industry` values from GET /prospects/filter-options (e.g. financial services). Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_title_levels": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Seniority of the current job title; entries with `value` one of exactly: cxo, vp, director, manager, senior, entry, owner, partner, training, unpaid (the `job_title_levels` list in GET /prospects/filter-options). Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_title_role": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Department of the current job title; entries with `value` one of the 24 `job_title_role` values in GET /prospects/filter-options (e.g. engineering, sales, finance) — `jobTitleRoleToSubRole` in the same response lists each role's sub-roles. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_title_sub_role": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Sub-department of the current job title; entries with `value` one of the 106 `job_title_sub_role` values in GET /prospects/filter-options (e.g. software, account_executive, data_science). Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_company_size": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Headcount bracket of the current employer; entries with `value` one of exactly: 1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+ — brackets only, so use `rangeInputs.job_company_employee_count` for an arbitrary headcount range. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_company_inferred_revenue": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Inferred annual revenue bracket of the current employer; entries with `value` one of exactly: $0-$1m, $1m-$10m, $10m-$25m, $25m-$50m, $50m-$100m, $100m-$250m, $250m-$500m, $500m-$1b, $1b-$10b, $10b+ (matched case-insensitively, so $1M-$10M also works). Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_company_industry": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Industry of the current employer; entries with `value` one of the same 147 industry values, listed under `job_company_industry` in GET /prospects/filter-options. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_company_location_country": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Country of the current employer's headquarters; entries with a lower-case `value` from the 249 `job_company_location_country` values in GET /prospects/filter-options (e.g. united states, germany) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_company_location_region": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Region or state of the current employer's headquarters; entries with a free-text lower-case `value` such as california — resolve names with GET /prospects/autocomplete?field=region."
                          },
                          "job_company_location_continent": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Continent of the current employer's headquarters; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "experience.company.location.continent": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Continent of the headquarters of any PAST employer; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "experience.title.levels": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Seniority of any past job title; entries with `value` one of exactly: cxo, vp, director, manager, senior, entry, owner, partner, training, unpaid. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "experience.title.role": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Department of any past job title; entries with `value` one of the 24 `experience.title.role` values in GET /prospects/filter-options — the same list as `job_title_role`. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "experience.title.sub_role": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Sub-department of any past job title; entries with `value` one of the 106 `experience.title.sub_role` values in GET /prospects/filter-options — the same list as `job_title_sub_role`. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "experience.company.location.country": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Country of the headquarters of any past employer; entries with a lower-case `value` from the 249 `experience.company.location.country` values in GET /prospects/filter-options (e.g. united states) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "experience.company.industry": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Industry of any past employer; entries with `value` one of the same 147 industry values, listed under `experience.company.industry` in GET /prospects/filter-options. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "languages.name": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Languages the person lists; entries with a lower-case `value` from the 526 `languages.name` values in GET /prospects/filter-options (e.g. english, german) — language NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "location_continent": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Continent the person lives in; entries with `value` one of exactly: africa, antarctica, asia, europe, north america, oceania, south america. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "location_country": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Country the person lives in; entries with a lower-case `value` from the 249 `location_country` values in GET /prospects/filter-options (e.g. united states, united kingdom) — country NAMES, never ISO codes. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "location_region": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Region or state the person lives in; entries with a free-text lower-case `value` such as california — resolve names with GET /prospects/autocomplete?field=region."
                          },
                          "education.degrees": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Degrees held; entries with `value` one of the 171 `education.degrees` values in GET /prospects/filter-options (e.g. bachelors, masters, master of business administration). Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "experience.company.type": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "status": {
                                  "type": "string",
                                  "enum": [
                                    "include",
                                    "exclude"
                                  ],
                                  "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                },
                                "value": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                },
                                "label": {
                                  "type": "string",
                                  "maxLength": 500,
                                  "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                }
                              },
                              "required": [
                                "status",
                                "value"
                              ]
                            },
                            "maxItems": 1000,
                            "description": "Type of any past employer; entries with `value` one of exactly: educational, government, nonprofit, private, public, public_subsidiary. Include values are OR-joined and every exclude applies; at most 1000 entries."
                          },
                          "job_company_name": {
                            "anyOf": [
                              {
                                "type": "string",
                                "maxLength": 500
                              },
                              {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "status": {
                                          "type": "string",
                                          "enum": [
                                            "include",
                                            "exclude"
                                          ],
                                          "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                        },
                                        "value": {
                                          "type": "string",
                                          "maxLength": 500,
                                          "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                        },
                                        "label": {
                                          "type": "string",
                                          "maxLength": 500,
                                          "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                        }
                                      },
                                      "required": [
                                        "status",
                                        "value"
                                      ]
                                    }
                                  ]
                                },
                                "maxItems": 1000
                              }
                            ],
                            "description": "Name of the current employer, lower-case (e.g. stripe); include/exclude entries, a bare string, or an array of strings (bare strings are includes) — resolve names with GET /prospects/autocomplete?field=company."
                          },
                          "job_company_website": {
                            "anyOf": [
                              {
                                "type": "string",
                                "maxLength": 500
                              },
                              {
                                "type": "array",
                                "items": {
                                  "anyOf": [
                                    {
                                      "type": "string",
                                      "maxLength": 500
                                    },
                                    {
                                      "type": "object",
                                      "properties": {
                                        "status": {
                                          "type": "string",
                                          "enum": [
                                            "include",
                                            "exclude"
                                          ],
                                          "description": "`include` matches the value; `exclude` removes profiles carrying it (includes OR together, every exclude applies)."
                                        },
                                        "value": {
                                          "type": "string",
                                          "maxLength": 500,
                                          "description": "The filter value (max 500 chars); for enum-backed fields use a value GET /prospects/filter-options lists for the field — other values match nothing."
                                        },
                                        "label": {
                                          "type": "string",
                                          "maxLength": 500,
                                          "description": "Optional display label as returned by GET /prospects/filter-options; accepted and ignored."
                                        }
                                      },
                                      "required": [
                                        "status",
                                        "value"
                                      ]
                                    }
                                  ]
                                },
                                "maxItems": 1000
                              }
                            ],
                            "description": "Website domain of the current employer (e.g. stripe.com — scheme, www and trailing slash are stripped); same value shapes as `job_company_name`; resolve with GET /prospects/autocomplete?field=website."
                          },
                          "full_name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, but matched as an EXACT lower-case term against the stored full name (e.g. ada nwosu): there is no partial matching, so a differently cased or partial name is accepted and silently matches nothing. A string, or an array of names that are OR-joined (the provider caps a terms list at 1000)."
                          },
                          "first_name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT lower-case term: a different case or a nickname is accepted and silently matches nothing. A string, or an array of names that are OR-joined. Cannot be stored in a saved search (422 SAVED_SEARCH_FILTERS_UNSUPPORTED)."
                          },
                          "last_name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT lower-case term: a different case or spelling is accepted and silently matches nothing. A string, or an array of names that are OR-joined. Cannot be stored in a saved search (422 SAVED_SEARCH_FILTERS_UNSUPPORTED)."
                          },
                          "sex": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "One of exactly: female, male. A string, or an array of both (OR-joined)."
                          },
                          "work_email": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT lower-case term against the stored work email: a different case or an alias is accepted and silently matches nothing. A string, or an array of addresses that are OR-joined."
                          },
                          "mobile_phone": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT term, so send E.164 with the leading + (e.g. +14155552671); any other formatting is accepted and silently matches nothing. A string, or an array of numbers that are OR-joined."
                          },
                          "personal_emails": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT lower-case term against every personal email on the profile: any other spelling is accepted and silently matches nothing. A string, or an array of addresses that are OR-joined."
                          },
                          "job_title": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Exact lower-case current job title (e.g. chief financial officer); a string or an array of titles — use `keywords` for partial matches and GET /prospects/autocomplete?field=title for suggestions."
                          },
                          "job_company_location_name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Locality of the current employer's headquarters as a PDL location name (e.g. san francisco, california, united states); resolve with GET /prospects/autocomplete?field=location."
                          },
                          "location_name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Where the person lives, as a PDL location name (e.g. london, greater london, united kingdom); resolve with GET /prospects/autocomplete?field=location."
                          },
                          "linkedin_url": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT term in the stored form linkedin.com/in/<slug> — no scheme, no www., no trailing slash; anything else is accepted and silently matches nothing. Prefer the top-level `linkedinUrl`, which IS normalised before matching. A string, or an array of URLs that are OR-joined."
                          },
                          "github_url": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT term in the stored form github.com/<username> — no scheme, no trailing slash; anything else is accepted and silently matches nothing. A string, or an array of URLs that are OR-joined."
                          },
                          "github_username": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT lower-case term against the stored GitHub username: a different case is accepted and silently matches nothing. A string, or an array of usernames that are OR-joined."
                          },
                          "facebook_url": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT term in the stored form facebook.com/<slug> — no scheme, no trailing slash; anything else is accepted and silently matches nothing. A string, or an array of URLs that are OR-joined."
                          },
                          "education.school.name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Lower-case name of a school attended (e.g. stanford university); resolve with GET /prospects/autocomplete?field=school."
                          },
                          "experience.title.name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Exact lower-case title held at any past job; a string or an array of titles."
                          },
                          "experience.company.name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Lower-case name of any past employer; a string or an array — resolve with GET /prospects/autocomplete?field=company."
                          },
                          "experience.company.website": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text: the website host of any past employer (e.g. stripe.com). The scheme, www. and a trailing slash are stripped and both the host+path and host-only forms are tried, so a full URL still matches; a host the provider does not store matches nothing. A string, or an array of hosts that are OR-joined."
                          },
                          "job_start_date": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Free text, matched as an EXACT term and NOT as a range: the stored start date of the current job, YYYY-MM or YYYY-MM-DD exactly as stored (most profiles store YYYY-MM), so 2023-05-01 does not match a profile stored as 2023-05. A string, or an array of dates that are OR-joined."
                          },
                          "skills": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Lower-case skill (e.g. python); a string, or an array of skills any of which may match — resolve with GET /prospects/autocomplete?field=skill."
                          },
                          "certifications.name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Lower-case certification name (e.g. pmp); a string or an array."
                          },
                          "experience.company.location.name": {
                            "anyOf": [
                              {
                                "type": "string"
                              },
                              {
                                "type": "number"
                              },
                              {
                                "type": "boolean"
                              },
                              {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              }
                            ],
                            "description": "Locality of any past employer's headquarters as a PDL location name."
                          },
                          "keywords": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 200
                            },
                            "maxItems": 25,
                            "description": "Free text: up to 25 terms (200 chars each), each matched against the current job title only and OR-joined, so any one may match. A bare term matches anywhere in the title (growth matches Head of Growth); a term carrying your own * or ? must match the WHOLE title (manager* starts with, *manager ends with, ? is exactly one character). Matching is case-insensitive. A term with no text other than wildcards is ignored, since it would match every title, and a list holding only such terms does not count as search criteria. This is the costliest filter the provider serves, so keep the list short."
                          },
                          "excludedKeywords": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "minLength": 1,
                              "maxLength": 200
                            },
                            "maxItems": 25,
                            "description": "Free text: up to 25 terms (200 chars each) using exactly the same matching rules as `keywords`, but REMOVING every prospect whose current job title matches any one of them — keywords [engineer] with excludedKeywords [infrastructure] keeps Engineer VP and drops Engineer VP Infrastructure. It reads the whole job title, so it also removes rows matched by `job_title`. A term with no text other than wildcards is ignored, since it would remove every prospect that has a job title. Exclusions only narrow a result set: on their own they are not search criteria and a request carrying nothing else is rejected."
                          },
                          "rangeInputs": {
                            "type": "object",
                            "properties": {
                              "job_company_employee_count": {
                                "type": "object",
                                "properties": {
                                  "min": {
                                    "type": "number",
                                    "description": "Inclusive lower bound (0 is treated as no bound)."
                                  },
                                  "max": {
                                    "type": "number",
                                    "description": "Inclusive upper bound."
                                  }
                                },
                                "description": "Headcount of the current employer; accepted values are whole numbers and both bounds are inclusive. A min of 0 is ignored rather than applied, so cap headcount with max alone."
                              },
                              "inferred_years_experience": {
                                "type": "object",
                                "properties": {
                                  "min": {
                                    "type": "number",
                                    "description": "Inclusive lower bound (0 is treated as no bound)."
                                  },
                                  "max": {
                                    "type": "number",
                                    "description": "Inclusive upper bound."
                                  }
                                },
                                "description": "Total years of professional experience; accepted values are whole numbers of years and both bounds are inclusive. A min of 0 is ignored rather than applied."
                              },
                              "job_company_total_funding_raised": {
                                "type": "object",
                                "properties": {
                                  "min": {
                                    "type": "number",
                                    "description": "Inclusive lower bound (0 is treated as no bound)."
                                  },
                                  "max": {
                                    "type": "number",
                                    "description": "Inclusive upper bound."
                                  }
                                },
                                "description": "Total funding raised by the current employer; accepted values are whole US dollars, not millions (10000000 means $10M), and both bounds are inclusive. A min of 0 is ignored rather than applied."
                              }
                            },
                            "description": "Numeric range filters, each key one of exactly: `job_company_employee_count`, `inferred_years_experience`, `job_company_total_funding_raised` (any other key is rejected). Each value is `{ min?, max? }` with at least one bound and min <= max; several ranges AND with each other and with every other filter."
                          }
                        },
                        "description": "People filters in the search vocabulary: include/exclude fields take `[{ status, value }]` entries, term fields a string or an array of strings, `rangeInputs` `{ min, max }` ranges — every field and its accepted values are listed by GET /prospects/filter-options. On this endpoint a value outside a field's listed vocabulary is refused with 422 VALIDATION_FAILED, naming the field and the value, before anything is billed. Must contain at least one non-empty value."
                      }
                    ],
                    "description": "Filters in the vocabulary of `type`: people filters as POST /prospects/search takes them (`first_name` / `last_name` cannot be stored and answer 422 SAVED_SEARCH_FILTERS_UNSUPPORTED), company filters as POST /companies/search takes them; at least one non-empty value either way."
                  }
                },
                "required": [
                  "title"
                ],
                "description": "A `title` plus `filters` written in the vocabulary of `type` (`people` by default); the search then opens identically in the product UI."
              }
            }
          }
        }
      }
    },
    "/business/saved-searches/{savedSearchId}": {
      "get": {
        "operationId": "getSavedSearch",
        "summary": "Get one saved search",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches.",
            "schema": {
              "type": "string",
              "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "savedSearch"
                  ],
                  "properties": {
                    "savedSearch": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "filters",
                        "ignoredFilterKeys",
                        "searchType",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "filters": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": true,
                          "description": "Filters in the vocabulary of `searchType`; null only when a stored people blob could not be translated at all."
                        },
                        "ignoredFilterKeys": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Stored keys with no equivalent search field, dropped from `filters` (always empty for company searches)."
                        },
                        "searchType": {
                          "type": "string",
                          "enum": [
                            "people",
                            "company"
                          ]
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "savedSearch": {
                    "id": "6a8de3161ea5e58766c32c88",
                    "title": "CoStar Group CXOs (US)",
                    "createdAt": "2026-08-25T18:46:46.159Z",
                    "updatedAt": "2026-08-25T18:46:46.159Z",
                    "filters": {
                      "job_title_levels": [
                        {
                          "status": "include",
                          "value": "cxo"
                        }
                      ],
                      "location_country": [
                        {
                          "status": "include",
                          "value": "united states"
                        }
                      ],
                      "job_company_name": [
                        {
                          "status": "include",
                          "value": "costar group"
                        }
                      ]
                    },
                    "ignoredFilterKeys": [],
                    "searchType": "people"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "One saved search of either kind, with its filters in the language the matching search endpoint accepts — POST /prospects/search for `searchType: people`, POST /companies/search for `searchType: company`. `ignoredFilterKeys` names stored keys with no equivalent search field, which were dropped from `filters`. A search that is not yours is 404, identically to one that does not exist.\n\nErrors:\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search."
      },
      "patch": {
        "operationId": "updateSavedSearch",
        "summary": "Rename a saved search or replace its filters",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches.",
            "schema": {
              "type": "string",
              "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "savedSearch"
                  ],
                  "properties": {
                    "savedSearch": {
                      "type": "object",
                      "required": [
                        "id",
                        "title",
                        "filters",
                        "ignoredFilterKeys",
                        "searchType",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "filters": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "additionalProperties": true,
                          "description": "Filters in the vocabulary of `searchType`; null only when a stored people blob could not be translated at all."
                        },
                        "ignoredFilterKeys": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "Stored keys with no equivalent search field, dropped from `filters` (always empty for company searches)."
                        },
                        "searchType": {
                          "type": "string",
                          "enum": [
                            "people",
                            "company"
                          ]
                        },
                        "createdAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "updatedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "savedSearch": {
                    "id": "6a8de3161ea5e58766c32c88",
                    "title": "CoStar Group CXOs (US + UK)",
                    "createdAt": "2026-08-25T18:46:46.159Z",
                    "updatedAt": "2026-08-25T18:47:08.908Z",
                    "filters": {
                      "job_title_levels": [
                        {
                          "status": "include",
                          "value": "cxo"
                        }
                      ],
                      "location_country": [
                        {
                          "status": "include",
                          "value": "united states"
                        },
                        {
                          "status": "include",
                          "value": "united kingdom"
                        }
                      ],
                      "job_company_name": [
                        {
                          "status": "include",
                          "value": "costar group"
                        }
                      ]
                    },
                    "ignoredFilterKeys": [],
                    "searchType": "people"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Rename a saved search, replace its filters, or both — at least one of `title` and `filters` is required. A search's type is immutable, so `filters` must speak the stored search's own language: the keys POST /prospects/search takes for a `people` search, the keys POST /companies/search takes for a `company` one. The replacement is wholesale, not a merge.\n\n`filters` is validated against the stored type after the row is loaded, so a rejected body answers 422 VALIDATION_FAILED with `param` naming the offending key — never SAVED_SEARCH_INVALID, which is reserved for a stored search that has itself gone stale. Keys that do not exist in the stored search's vocabulary are ignored rather than named, so filters sent in the wrong vocabulary are reported as \"filters must contain at least one non-empty value\"; check `searchType` first. The only two people filter fields that cannot round-trip through the product's filter rail are `first_name` and `last_name`; either one answers 422 SAVED_SEARCH_FILTERS_UNSUPPORTED naming the field.\n\nErrors:\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `422` `SAVED_SEARCH_FILTERS_UNSUPPORTED` — `filters` names `first_name` or `last_name` — the only two people filter fields with no saved-search equivalent; `param` names the field.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "New display name (1-255 chars)."
                  },
                  "filters": {
                    "type": "object",
                    "properties": {},
                    "description": "Replacement filters in the stored search's own vocabulary — people searches take the keys of POST /prospects/search, company searches the keys of POST /companies/search — validated against the stored type after loading; at least one non-empty value and only accepted enum values (422 VALIDATION_FAILED otherwise, naming the offending key)."
                  }
                },
                "description": "At least one of `title` or `filters`; a search's type cannot change."
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteSavedSearch",
        "summary": "Delete a saved search",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches.",
            "schema": {
              "type": "string",
              "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Permanently delete one saved search of either kind. Nothing else is touched: lists, campaigns and contacts saved from the search are unaffected. Deleting is not idempotent — repeating the call answers 404 SAVED_SEARCH_NOT_FOUND, as does a search that is not yours.\n\nErrors:\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search."
      }
    },
    "/business/saved-searches/{savedSearchId}/run": {
      "post": {
        "operationId": "runSavedSearch",
        "summary": "Replay a saved search",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "savedSearchId",
            "in": "path",
            "required": true,
            "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches.",
            "schema": {
              "type": "string",
              "description": "Id of the saved search (24-character hex ObjectId), as returned by GET /saved-searches."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "profiles",
                    "scrollToken",
                    "total",
                    "filters",
                    "ignoredFilterKeys"
                  ],
                  "properties": {
                    "profiles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "required": [
                          "linkedinConnectedAccountIds",
                          "linkedinInvitationSentAccountIds"
                        ],
                        "properties": {
                          "_id": {
                            "type": "string",
                            "description": "Fuse's own id for the cached person record; stable across searches and the id `savedProfile` refers to. Absent on a row the cache could not store."
                          },
                          "pdlId": {
                            "type": "string",
                            "description": "The provider's person id; always present — on a row the cache could not store it is the only id the row carries."
                          },
                          "savedProfile": {
                            "type": "boolean",
                            "description": "Whether this person is already a contact in one of your lists. Absent on a row the cache could not store, which cannot be matched against your contacts."
                          },
                          "savedBy": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Id of the workspace member who saved the contact; null when it is not saved, absent on a row the cache could not store."
                          },
                          "linkedinConnectedAccountIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Ids of your connected LinkedIn accounts already connected to this person."
                          },
                          "linkedinInvitationSentAccountIds": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "Ids of your connected LinkedIn accounts that have already sent this person an invitation."
                          },
                          "linkedin_url": {
                            "type": "string"
                          },
                          "full_name": {
                            "type": "string"
                          },
                          "sex": {
                            "type": "string"
                          },
                          "industry": {
                            "type": "string"
                          },
                          "job_title": {
                            "type": "string"
                          },
                          "job_title_role": {
                            "type": "string"
                          },
                          "job_title_sub_role": {
                            "type": "string"
                          },
                          "job_title_class": {
                            "type": "string"
                          },
                          "job_title_levels": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "job_company_name": {
                            "type": "string"
                          },
                          "job_company_website": {
                            "type": "string"
                          },
                          "location_name": {
                            "type": "string"
                          },
                          "profile_score": {
                            "type": "string"
                          },
                          "activity_score": {
                            "type": "string"
                          },
                          "dataset_version": {
                            "type": "string"
                          },
                          "pdl_version": {
                            "type": [
                              "string",
                              "null"
                            ]
                          },
                          "job_change_detected_at": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "scrollToken": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Send back as `scrollToken` for the next page; null when the provider returned no continuation."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of people matching the stored filters, not the page size."
                    },
                    "filters": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The stored filters translated into the POST /prospects/search vocabulary — send these to reproduce the run there."
                    },
                    "ignoredFilterKeys": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Stored keys with no equivalent search field, dropped before running; the product's UI skips them too."
                    }
                  }
                },
                "example": {
                  "profiles": [
                    {
                      "_id": "6a8dde1f5792025bcc9e9f61",
                      "pdlId": "gAkE2YBBdEZJ1b2iSrUKCQ_0000",
                      "linkedin_url": "linkedin.com/in/chrismumford",
                      "dataset_version": "35.1",
                      "pdl_version": "35.1",
                      "job_change_detected_at": null,
                      "createdAt": "2026-08-25T18:25:35.591Z",
                      "updatedAt": "2026-08-25T18:46:56.528Z",
                      "full_name": "chris mumford",
                      "sex": "male",
                      "industry": "real estate",
                      "job_title": "chief marketing officer - marketplaces",
                      "job_title_role": "marketing",
                      "job_title_class": "sales_and_marketing",
                      "job_title_levels": [
                        "cxo"
                      ],
                      "job_company_name": "costar group",
                      "job_company_website": "costargroup.com",
                      "location_name": "richmond, virginia, united states",
                      "profile_score": "positive signals",
                      "activity_score": "positive signals",
                      "savedProfile": false,
                      "savedBy": null,
                      "linkedinConnectedAccountIds": [],
                      "linkedinInvitationSentAccountIds": []
                    }
                  ],
                  "scrollToken": "20919$3.0004249",
                  "total": 8,
                  "filters": {
                    "job_title_levels": [
                      {
                        "status": "include",
                        "value": "cxo"
                      }
                    ],
                    "location_country": [
                      {
                        "status": "include",
                        "value": "united states"
                      }
                    ],
                    "job_company_name": [
                      {
                        "status": "include",
                        "value": "costar group"
                      }
                    ]
                  },
                  "ignoredFilterKeys": []
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Replay a stored PEOPLE saved search. Equivalent to POST /prospects/search with `savedSearchId`; both echo the resolved filters, and this one always includes `ignoredFilterKeys` because the source is always a stored search.\n\nThe optional body carries only the caller's half of the search — `size`, `scrollToken`, `linkedinUrl` — or may be omitted entirely. The stored filters ARE the search: any other key, `filters` included, is rejected with 422 VALIDATION_FAILED naming it rather than silently ignored. That body is validated on its own before the stored search is loaded, so a bad `size` is reported as your error; SAVED_SEARCH_INVALID means the STORED filters no longer run.\n\nA company saved search cannot be replayed here — it answers 422 SAVED_SEARCH_TYPE_MISMATCH; run it with POST /companies/search and `savedSearchId` instead.\n\nRows and paging behave exactly as in POST /prospects/search: provider person records plus Fuse's `pdlId`, the LinkedIn relation ids and — on every row the cache could store — `_id` and `savedProfile` / `savedBy`, a nullable `scrollToken`, and the true match `total`. No row carries an email address or a phone number, enrichment history included. Billing: 2 credits per requested profile pre-checked, 2 credits per profile returned debited. (Enforced by the public row transformer, which removes Fuse's enrichment overlay and the provider's own work_email, personal_emails, recommended_personal_email, mobile_phone and phone_numbers before the row is returned.)\n\nErrors:\n- `402` `INSUFFICIENT_CREDITS` — The balance does not cover 2 credits per requested profile; nothing was billed.\n- `404` `SAVED_SEARCH_NOT_FOUND` — No saved search of yours has that id.\n- `422` `VALIDATION_FAILED` — The request failed the declared schema; `param` names the offending key and `message` quotes the rule it broke.\n- `422` `SAVED_SEARCH_TYPE_MISMATCH` — The saved search stores COMPANY filters, which this endpoint cannot run; `param` is `savedSearchId`. Run it with POST /companies/search and `savedSearchId` instead.\n- `422` `SAVED_SEARCH_INVALID` — The STORED filters no longer form a runnable search — every value was retired, or the blob translates to nothing. Never used for anything the caller sent.\n- `422` `SEARCH_FILTERS_INVALID` — The provider rejected the assembled query as malformed.\n- `429` `RATE_LIMITED` — Per-token rate limit for this bucket exhausted; retry after the window in the RateLimit-Reset header.\n- `500` `UNEXPECTED_ERROR` — The request failed inside the service; nothing was billed and the request_id identifies the failure.\n\nRequires one of the following token scopes: search.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "size": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 10,
                    "description": "Profiles per page (1-100, default 10); the search pre-checks 2 credits per requested profile and debits 2 credits per profile returned."
                  },
                  "scrollToken": {
                    "type": "string",
                    "description": "The `scrollToken` returned by the previous page, sent together with the same filter source, to fetch the next page."
                  },
                  "linkedinUrl": {
                    "type": "string",
                    "description": "A LinkedIn profile URL to look up one person (normalised before matching); counts as search criteria on its own."
                  }
                },
                "description": "Optional paging and lookup overrides for the replay — `size`, `scrollToken`, `linkedinUrl` — or no body at all. The stored filters are the search; any other key, `filters` included, is rejected with 422 VALIDATION_FAILED."
              }
            }
          }
        }
      }
    },
    "/business/folders": {
      "get": {
        "operationId": "listFolders",
        "summary": "List the token owner's list folders of one kind",
        "tags": [
          "Folders"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": true,
            "description": "Folder kind to list: contactList or companyList (list folders), campaign (campaign folders) or agent (agent folders).",
            "schema": {
              "type": "string",
              "enum": [
                "contactList",
                "companyList",
                "campaign",
                "agent"
              ],
              "description": "Folder kind to list: contactList or companyList (list folders), campaign (campaign folders) or agent (agent folders)."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "folders"
                  ],
                  "properties": {
                    "folders": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "type"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "contactList",
                              "companyList",
                              "campaign",
                              "agent"
                            ]
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "folders": [
                    {
                      "id": "68a1f9aa9c41d20014b3f101",
                      "name": "Q3 pipeline",
                      "type": "contactList"
                    },
                    {
                      "id": "68a1f9aa9c41d20014b3f102",
                      "name": "Partners",
                      "type": "contactList"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The token owner's folders of one kind: `contactList` and `companyList` folders organise lists (the `folderId` on `GET /business/lists` rows and `PATCH /business/lists/{listId}`), `campaign` folders organise campaigns, and `agent` folders organise agents. Not paginated — every folder of the kind is returned.\n\nErrors:\n- `422` `VALIDATION_FAILED` — type missing or outside contactList|companyList|campaign|agent.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n- `400` `INVALID_REQUEST` — agent/campaign kinds only: the owning service rejected the request (its own code is relayed when it sends one).\n\nRequires one of the following token scopes: lists."
      },
      "post": {
        "operationId": "createFolder",
        "summary": "Create a list folder",
        "tags": [
          "Folders"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "folder"
                  ],
                  "properties": {
                    "folder": {
                      "type": "object",
                      "required": [
                        "id",
                        "name",
                        "type"
                      ],
                      "properties": {
                        "id": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "name": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "contactList",
                            "companyList",
                            "campaign",
                            "agent"
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "folder": {
                    "id": "68a1f9aa9c41d20014b3f101",
                    "name": "Q3 pipeline",
                    "type": "contactList"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Creates a folder of the given kind (`contactList` by default). List-folder names are unique per kind (409 FOLDER_NAME_TAKEN); campaign and agent folders are created in their own services and answer their codes. Put lists into the folder with `PATCH /business/lists/{listId}` (`folderId`).\n\nErrors:\n- `409` `FOLDER_NAME_TAKEN` — A folder of that kind already carries the name.\n- `400` `INVALID_REQUEST` — campaign/agent kinds only: the owning service rejected the request.\n- `422` `VALIDATION_FAILED` — name missing/blank/over 120 characters, type outside the enum, or an unknown body key.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted, or the owning service (campaign/agent folders) refused the call.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Folder name (1-120 characters); unique per kind, or the call answers 409 FOLDER_NAME_TAKEN."
                  },
                  "type": {
                    "type": "string",
                    "enum": [
                      "contactList",
                      "companyList",
                      "campaign",
                      "agent"
                    ],
                    "default": "contactList",
                    "description": "Kind of folder to create (default contactList): contactList or companyList (list folders), campaign or agent."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/business/folders/{folderId}": {
      "patch": {
        "operationId": "renameFolder",
        "summary": "Rename a folder",
        "tags": [
          "Folders"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the folder (from GET /business/folders).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the folder (from GET /business/folders)."
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Kind of the folder being changed: required as campaign or agent for those folder kinds; omit (or pass contactList/companyList) for a list folder, which resolves by id alone.",
            "schema": {
              "type": "string",
              "enum": [
                "contactList",
                "companyList",
                "campaign",
                "agent"
              ],
              "description": "Kind of the folder being changed: required as campaign or agent for those folder kinds; omit (or pass contactList/companyList) for a list folder, which resolves by id alone."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "folder"
                  ],
                  "properties": {
                    "folder": {
                      "type": "object",
                      "required": [
                        "id",
                        "name"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "folder": {
                    "id": "68a1f9aa9c41d20014b3f101",
                    "name": "Q4 pipeline"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Renames a folder. List folders (`contactList`/`companyList`) resolve by id alone; pass `?type=campaign` or `?type=agent` to rename a campaign or agent folder, which live in their own services. The new name must be unused among folders of the same kind (409 FOLDER_NAME_TAKEN). The response is the rename echo — the folder's id and its new name.\n\nErrors:\n- `404` `FOLDER_NOT_FOUND` — No folder with that id (of the routed kind) belongs to the token owner.\n- `409` `FOLDER_NAME_TAKEN` — Another folder of the same kind already has that name.\n- `400` `INVALID_REQUEST` — campaign/agent kinds only: the owning service rejected the request.\n- `422` `VALIDATION_FAILED` — folderId not a 24-hex id, name missing/blank/over 120 characters, or type outside the enum.\n- `429` `RATE_LIMITED` — The lists rate bucket (120 requests/minute, 10,000/day per token owner) is exhausted, or the owning service (campaign/agent folders) refused the call.\n\nRequires one of the following token scopes: lists.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "New folder name (1-120 characters); a name already used by another folder of the same kind answers 409 FOLDER_NAME_TAKEN."
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteFolder",
        "summary": "Delete a folder (its lists move to the root)",
        "tags": [
          "Folders"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "folderId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of the folder (from GET /business/folders).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of the folder (from GET /business/folders)."
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Kind of the folder being changed: required as campaign or agent for those folder kinds; omit (or pass contactList/companyList) for a list folder, which resolves by id alone.",
            "schema": {
              "type": "string",
              "enum": [
                "contactList",
                "companyList",
                "campaign",
                "agent"
              ],
              "description": "Kind of the folder being changed: required as campaign or agent for those folder kinds; omit (or pass contactList/companyList) for a list folder, which resolves by id alone."
            }
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Deletes a folder; the lists (or campaigns/agents) it held are not deleted and move back to the root. List folders resolve by id alone; pass `?type=campaign` or `?type=agent` for those folder kinds.\n\nErrors:\n- `404` `FOLDER_NOT_FOUND` — No folder with that id (of the routed kind) belongs to the token owner.\n- `400` `INVALID_REQUEST` — campaign/agent kinds only: the owning service rejected the request.\n- `422` `VALIDATION_FAILED` — folderId not a 24-hex id, or type outside the enum.\n- `429` `RATE_LIMITED` — The lists rate bucket is exhausted.\n\nRequires one of the following token scopes: lists."
      }
    },
    "/business/contacts/resolve": {
      "post": {
        "operationId": "resolveContactByLinkedinUrl",
        "summary": "Resolve the caller's contact by LinkedIn URL",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "contactId"
                  ],
                  "properties": {
                    "contactId": {
                      "type": "string",
                      "description": "Id of the contact for that LinkedIn URL."
                    }
                  }
                },
                "example": {
                  "contactId": "68a1f2c89c41d20014b3e955"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Looks up the contact record for a LinkedIn profile URL and returns its `contactId`, the id every other contacts endpoint and every list row uses. The URL is normalised before matching, so `https://www.linkedin.com/in/ada-nwosu/` and `linkedin.com/in/ada-nwosu` resolve the same contact; a value that carries no `linkedin.com/` path is rejected with 422. Contacts are canonical records: a match is returned whether the person reached your workspace through search, an upload or an enrichment, while contacts your team created by hand are matched within your team only. Answers 404 CONTACT_NOT_FOUND when no contact exists for that URL; create it by adding the person to a list (`POST /business/lists/{listId}/contacts`) and resolve again. Read-only and free: it never creates or changes a contact.\n\nErrors:\n- `404` `CONTACT_NOT_FOUND` — No contact exists for that LinkedIn URL.\n- `422` `INVALID_REQUEST` — The URL could not be read as a LinkedIn profile.\n- `422` `VALIDATION_FAILED` — The body failed validation — a missing linkedinUrl, one over 500 characters, or one that is not a linkedin.com profile URL.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: contacts.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "linkedinUrl": {
                    "type": "string",
                    "maxLength": 500,
                    "description": "The contact's LinkedIn profile URL (max 500 characters). Any form is accepted as long as it contains linkedin.com/in/...: the protocol, www prefix and trailing slash are ignored when matching."
                  }
                },
                "required": [
                  "linkedinUrl"
                ]
              }
            }
          }
        }
      }
    },
    "/business/contacts/{contactId}": {
      "patch": {
        "operationId": "updateContact",
        "summary": "Set a contact's primary email and/or phone",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "description": "Id of the contact: the row id from GET /business/lists/{listId}/rows, or the contactId returned by POST /business/contacts/resolve.",
            "schema": {
              "type": "string",
              "description": "Id of the contact: the row id from GET /business/lists/{listId}/rows, or the contactId returned by POST /business/contacts/resolve."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "contact"
                  ],
                  "properties": {
                    "contact": {
                      "type": "object",
                      "required": [
                        "id",
                        "primaryEmail",
                        "primaryPhone"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Id of the contact."
                        },
                        "primaryEmail": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The contact's primary email after the update; null when it has none."
                        },
                        "primaryPhone": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "The contact's primary phone after the update; null when it has none."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "contact": {
                    "id": "68a1f2c89c41d20014b3e955",
                    "primaryEmail": "ada@brightpay.com",
                    "primaryPhone": "+14155552671"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Sets which of the contact's known emails and phone numbers are its primary ones. Primaries are chosen by value: `primaryEmail` must be one of the addresses already on the contact and `primaryPhone` one of its phone numbers, written exactly as they appear on the list row (`emails[].email`, `phones[].phoneNumber`); a value the contact does not carry is rejected with 422 PRIMARY_VALUE_NOT_ON_CONTACT and nothing is changed. The call promotes an existing value and never adds a new one — enrich the contact to add addresses or numbers. Send either field or both; the response reports both primaries as they now stand. Free to call.\n\nErrors:\n- `404` `CONTACT_NOT_FOUND` — No contact with that id exists.\n- `422` `PRIMARY_VALUE_NOT_ON_CONTACT` — The value is not one the contact already carries; `param` names which of primaryEmail / primaryPhone was rejected and nothing was changed.\n- `422` `VALIDATION_FAILED` — The body failed validation, including a body with neither primaryEmail nor primaryPhone.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: contacts.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "primaryEmail": {
                    "type": "string",
                    "format": "email",
                    "maxLength": 320,
                    "description": "Email address to make the contact's primary email (a valid address, max 320 characters). It must be one of the emails the contact already carries: this promotes an existing value and never adds a new one."
                  },
                  "primaryPhone": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 32,
                    "description": "Phone number to make the contact's primary phone (3-32 characters, written exactly as it appears in the contact's phones). It must be one of the phone numbers the contact already carries: this promotes an existing value and never adds a new one."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/business/contacts/{contactId}/activities": {
      "get": {
        "operationId": "listContactActivities",
        "summary": "A contact's activity timeline",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "description": "Id of the contact: the row id from GET /business/lists/{listId}/rows, or the contactId returned by POST /business/contacts/resolve.",
            "schema": {
              "type": "string",
              "description": "Id of the contact: the row id from GET /business/lists/{listId}/rows, or the contactId returned by POST /business/contacts/resolve."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of activities per page, 1-100 (default 100). It bounds the page of history; the first page can carry a few entries on top of it (campaign steps still scheduled, and LinkedIn activity, neither of which pages on its own), so read `activities.length` rather than assuming `limit`.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 100,
              "description": "Maximum number of activities per page, 1-100 (default 100). It bounds the page of history; the first page can carry a few entries on top of it (campaign steps still scheduled, and LinkedIn activity, neither of which pages on its own), so read `activities.length` rather than assuming `limit`."
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque cursor copied from the previous page's `nextCursor` (max 500 characters). Omit it for the first page.",
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 500,
              "description": "Opaque cursor copied from the previous page's `nextCursor` (max 500 characters). Omit it for the first page."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "contactId",
                    "activities",
                    "nextCursor"
                  ],
                  "properties": {
                    "contactId": {
                      "type": "string",
                      "description": "Id of the contact."
                    },
                    "activities": {
                      "type": "array",
                      "description": "One page of the timeline, newest first, with any campaign steps still scheduled pinned at the top. The first page can hold a few entries more than `limit`.",
                      "items": {
                        "type": "object",
                        "description": "One timeline entry. Every key is present on every entry; which of them are filled depends on `channel`.",
                        "required": [
                          "id",
                          "channel",
                          "status",
                          "direction",
                          "campaignId",
                          "subject",
                          "body",
                          "sentAt",
                          "receivedAt",
                          "scheduledAt",
                          "from",
                          "to",
                          "linkedinUrl",
                          "phoneNumber",
                          "callTranscript",
                          "callRecordingUrl",
                          "callDisposition"
                        ],
                        "properties": {
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Id of the activity (the provider message id on LinkedIn rows)."
                          },
                          "channel": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Where the activity happened: `email`, `linkedin_message`, `linkedin_connection`, `inmail`, `linkedin_visit`, `linkedin_like`, `non_campaign_call` (a call that was placed, campaign or one-off), `dialer` (a campaign call step still scheduled), `todo` (a manual campaign step), and `crm_activity` for a note, meeting or task logged in a connected CRM. A CRM's own emails and calls arrive as `email` and `non_campaign_call` like any other."
                          },
                          "status": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Delivery state, in the vocabulary of the store the row came from. Campaign steps: scheduled, approval_required, action_required, sent, replied, skipped, stopped, overwritten, preview, failed. Calls: answered, answered-subsequent, notAnswered, callEnded, answeredByMachine, message-played, busy, inbound-forwarding-not-accepted, failed, cancelled, pick-up-race-dropped. LinkedIn: sent, replied. Activity logged by a connected CRM: logged."
                          },
                          "direction": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "inbound",
                              "outbound",
                              null
                            ],
                            "description": "Direction when the channel records one (calls always do); null otherwise."
                          },
                          "campaignId": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Campaign the activity belongs to; null for activity outside a campaign."
                          },
                          "subject": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Email subject; null on every other channel."
                          },
                          "body": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "The text the activity carries: the email body, the LinkedIn message text, or — on call rows — the notes the rep saved against the call. Null when the activity carries no text. Read `contentType` before rendering it: the same key carries HTML and plain text, and a long body can arrive shortened to a snippet.",
                            "required": [
                              "contentType",
                              "content"
                            ],
                            "properties": {
                              "contentType": {
                                "type": "string",
                                "enum": [
                                  "html",
                                  "text"
                                ],
                                "description": "How to read `content`."
                              },
                              "content": {
                                "type": "string",
                                "description": "The body text, in the form `contentType` names; a long body can be shortened to a snippet."
                              }
                            }
                          },
                          "sentAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "When an outbound activity went out."
                          },
                          "receivedAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "When an inbound activity arrived."
                          },
                          "scheduledAt": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "format": "date-time",
                            "description": "For a campaign step that has not gone out yet: when it will."
                          },
                          "from": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "description": "Email rows: the sender; null when the channel records no address.",
                            "required": [
                              "name",
                              "address"
                            ],
                            "properties": {
                              "name": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Display name when known."
                              },
                              "address": {
                                "type": "string",
                                "description": "Email address."
                              }
                            }
                          },
                          "to": {
                            "type": "array",
                            "description": "Email rows: the recipients; empty on channels that record no address.",
                            "items": {
                              "type": "object",
                              "required": [
                                "name",
                                "address"
                              ],
                              "properties": {
                                "name": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "Display name when known."
                                },
                                "address": {
                                  "type": "string",
                                  "description": "Email address."
                                }
                              }
                            }
                          },
                          "linkedinUrl": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "LinkedIn rows: the profile the message or invitation was sent to."
                          },
                          "phoneNumber": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Call rows: the number dialled."
                          },
                          "callTranscript": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Call rows: the transcript when one was produced."
                          },
                          "callRecordingUrl": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Call rows: a time-limited recording URL when a recording exists."
                          },
                          "callDisposition": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "enum": [
                              "connected-positive",
                              "connected-neutral",
                              "connected-negative",
                              "connected-follow-up",
                              "left-voicemail",
                              "no-answer",
                              "connected-busy",
                              "bad-wrong-number",
                              "not-specified",
                              null
                            ],
                            "description": "Call rows: the outcome the rep recorded. `not-specified` is the default a call carries until the rep sets one; null on every other channel."
                          }
                        }
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Cursor for the next page; null on the last page."
                    }
                  }
                },
                "example": {
                  "contactId": "68a1f2c89c41d20014b3e955",
                  "activities": [
                    {
                      "id": "68a2b1c09c41d20014b41a10",
                      "channel": "email",
                      "status": "replied",
                      "direction": null,
                      "campaignId": "68a201559c41d20014b40111",
                      "subject": "Re: Quick question about Brightpay's Q3 hiring",
                      "body": {
                        "contentType": "html",
                        "content": "<p>Thanks Sam, happy to chat on Thursday.</p>"
                      },
                      "sentAt": null,
                      "receivedAt": "2026-08-21T14:02:11.000Z",
                      "scheduledAt": null,
                      "from": {
                        "name": "Ada Nwosu",
                        "address": "ada@brightpay.com"
                      },
                      "to": [
                        {
                          "name": "Sam Rivera",
                          "address": "sam@acme.com"
                        }
                      ],
                      "linkedinUrl": null,
                      "phoneNumber": null,
                      "callTranscript": null,
                      "callRecordingUrl": null,
                      "callDisposition": null
                    },
                    {
                      "id": "68a2a0114773c751a92de55d",
                      "channel": "non_campaign_call",
                      "status": "answered",
                      "direction": "outbound",
                      "campaignId": null,
                      "subject": null,
                      "body": {
                        "contentType": "html",
                        "content": "- Asked for pricing on the 10-seat plan<br>- Sending the deck, following up Thursday"
                      },
                      "sentAt": "2026-08-20T16:47:18.434Z",
                      "receivedAt": null,
                      "scheduledAt": null,
                      "from": null,
                      "to": [],
                      "linkedinUrl": null,
                      "phoneNumber": "+14155552671",
                      "callTranscript": "Ada: Hello? — Sam: Hi Ada, Sam from Acme, is now a bad time?",
                      "callRecordingUrl": "https://fuse-call-recordings.s3.us-east-1.amazonaws.com/68a1f2c8/68a2a0114773c751a92de55d.wav?X-Amz-Expires=3600&X-Amz-Signature=8a3f0b7c9d2e4f1a6b5c8d7e9f0a1b2c",
                      "callDisposition": "connected-positive"
                    },
                    {
                      "id": "OmgR3-p-X9mOYqVQgiQ4Hw",
                      "channel": "linkedin_message",
                      "status": "sent",
                      "direction": null,
                      "campaignId": "68a201559c41d20014b40111",
                      "subject": null,
                      "body": {
                        "contentType": "text",
                        "content": "Hi Ada, loved your post on payroll automation. Open to a quick chat next week?"
                      },
                      "sentAt": "2026-08-19T09:15:00.000Z",
                      "receivedAt": null,
                      "scheduledAt": null,
                      "from": null,
                      "to": [],
                      "linkedinUrl": "linkedin.com/in/ada-nwosu",
                      "phoneNumber": null,
                      "callTranscript": null,
                      "callRecordingUrl": null,
                      "callDisposition": null
                    }
                  ],
                  "nextCursor": "3"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "The contact's activity timeline as the app's activity drawer shows it, newest first: campaign emails sent and replies received, LinkedIn invitations and messages, dialer calls with their transcript, recording, disposition and the notes the rep saved, activity logged by a connected CRM, and campaign steps still scheduled to go out (`scheduledAt` set, `sentAt` null). Every entry carries the same keys whatever the channel, so `channel` tells you which of them are filled: email rows carry `subject`, `body`, `from` and `to`; LinkedIn rows carry the message text in `body` and the profile in `linkedinUrl`; call rows carry `phoneNumber`, `direction`, `callTranscript`, `callRecordingUrl`, `callDisposition`, and the call notes — not a message — in `body`. Page with `limit` (1-100, default 100) and `cursor`: copy `nextCursor` from the previous page and stop when it is null. `limit` bounds the page of history; the first page can carry a few entries on top of it (campaign steps still scheduled, and LinkedIn activity, neither of which pages on its own), so read `activities.length` rather than assuming `limit`. Free to call.\n\nErrors:\n- `404` `CONTACT_NOT_FOUND` — No contact with that id exists.\n- `422` `VALIDATION_FAILED` — The path, query or body failed validation; `param` names the offending field and `message` says why.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The timeline could not be assembled; quote request_id to support.\n\nRequires one of the following token scopes: contacts."
      }
    },
    "/business/contacts/dedupe-scan": {
      "post": {
        "operationId": "startDedupeScan",
        "summary": "Start an async duplicate-contact scan (returns a jobId)",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jobId"
                  ],
                  "properties": {
                    "jobId": {
                      "type": "string",
                      "description": "Id of the scan job; poll GET /business/contacts/dedupe-jobs/{jobId} and pass it to POST /business/contacts/dedupe-merge."
                    }
                  }
                },
                "example": {
                  "jobId": "68a1f5209c41d20014b3eb11"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Starts an async scan of the workspace's saved contacts (the whole team's pool, Fuse and custom) for duplicates: contacts that match EXACTLY on every field in `matchFields`. The selection must carry at least one unique identifier (`linkedinUrl`, `email`, `phone`) or at least 3 profile fields (`fullName`, `jobTitle`, `industry`, `location`, `companyName`, `companyDomain`) — anything weaker would group unrelated people and is rejected. Async: 202 returns a `jobId`; poll `GET /business/contacts/dedupe-jobs/{jobId}` until `status` is `completed`, then read `scanResult.groups`. Each group carries a `mergePreview` (what the surviving contact will look like) so the result can be reviewed before anything is merged; scanning changes nothing and spends no credits. The result stores at most 200 groups (`truncated` is true when more were found — merge and scan again), and a group larger than 50 contacts is skipped as a too-weak selection (`skippedOversizedGroups` counts them). Rate limit: 120 requests per minute, 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares.\n\nErrors:\n- `422` `VALIDATION_FAILED` — matchFields is missing, carries an unknown field, or fails the selection-strength rule.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: contacts.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "matchFields": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "linkedinUrl",
                        "email",
                        "phone",
                        "fullName",
                        "jobTitle",
                        "industry",
                        "location",
                        "companyName",
                        "companyDomain"
                      ]
                    },
                    "minItems": 1,
                    "maxItems": 9,
                    "description": "Fields duplicates must match exactly on: any combination of linkedinUrl, email, phone, fullName, jobTitle, industry, location, companyName, companyDomain. The selection must include at least one unique identifier (linkedinUrl, email or phone) OR at least 3 of the profile fields — a weaker selection would group unrelated people and is rejected."
                  }
                },
                "required": [
                  "matchFields"
                ]
              }
            }
          }
        }
      }
    },
    "/business/contacts/dedupe-merge": {
      "post": {
        "operationId": "startDedupeMerge",
        "summary": "Merge the duplicate groups a completed scan found",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jobId"
                  ],
                  "properties": {
                    "jobId": {
                      "type": "string",
                      "description": "Id of the merge job; poll GET /business/contacts/dedupe-jobs/{jobId}."
                    }
                  }
                },
                "example": {
                  "jobId": "68a1f6039c41d20014b3ec42"
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Merges the duplicate groups a completed scan found — every group, or just the `groupIds` subset (16-hex `groupId` values from the scan result). Async: 202 returns a `jobId`; poll `GET /business/contacts/dedupe-jobs/{jobId}` until `status` is `completed`, then read `mergeResult` for the totals. Within each group the surviving contact is chosen by the merge contract (a Fuse contact beats a custom one; among custom-only groups the most recently created wins), its empty fields are filled from the other members, all emails and phones are combined, custom-column values are carried over, and the losing contacts are archived with their list memberships repointed to the survivor — every list that held a duplicate ends up holding the surviving contact instead. Merging cannot be undone. Two Fuse contacts with conflicting identities (different PDL ids or different LinkedIn URLs) are never combined, even when the scan grouped them; such groups are split or skipped, so `mergeResult.mergedGroups` can be lower than the number of groups submitted. The scan job must be `completed` (409 SCAN_NOT_COMPLETED while it still runs) and is consumed as stored — unknown `groupIds` merge nothing. Rate limit: 120 requests per minute, 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares.\n\nErrors:\n- `404` `SCAN_NOT_FOUND` — No dedupe scan job with that id (it may have expired or belong to another workspace).\n- `409` `SCAN_NOT_COMPLETED` — The scan is still running — poll it until status is completed, then retry.\n- `422` `SCAN_HAS_NO_GROUPS` — The scan completed but found no duplicate groups; there is nothing to merge.\n- `422` `VALIDATION_FAILED` — scanJobId is not a 24-hex id, or groupIds carries something other than 1-200 unique 16-hex ids.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares; retry after Retry-After.\n- `500` `UNEXPECTED_ERROR` — The request could not be completed; quote request_id to support.\n\nRequires one of the following token scopes: contacts.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "scanJobId": {
                    "type": "string",
                    "description": "Id of a completed dedupe scan job — the `jobId` returned by POST /business/contacts/dedupe-scan."
                  },
                  "groupIds": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 200,
                    "description": "Optional subset of the scan's groups to merge, by `groupId` (16-hex ids from the scan result's `groups`). Omit it to merge every group the scan found."
                  }
                },
                "required": [
                  "scanJobId"
                ]
              }
            }
          }
        }
      }
    },
    "/business/contacts/dedupe-jobs/{jobId}": {
      "get": {
        "operationId": "getDedupeJob",
        "summary": "Poll a dedupe scan or merge job (groups / totals when completed)",
        "tags": [
          "Contacts"
        ],
        "security": [
          {
            "basicAuth": []
          }
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "24-character hex id of an async job, as returned with the 202 that started it (POST /business/lists/{listId}/export).",
            "schema": {
              "type": "string",
              "description": "24-character hex id of an async job, as returned with the 202 that started it (POST /business/lists/{listId}/export)."
            }
          },
          {
            "name": "pageNum",
            "in": "query",
            "required": false,
            "description": "1-based page number over the scan's stored groups (default 1); groups are ordered largest first.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1,
              "description": "1-based page number over the scan's stored groups (default 1); groups are ordered largest first."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size: how many duplicate groups to return per page (1-200, default 50). A scan stores at most 200 groups, so limit=200 returns the whole result in one page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50,
              "description": "Page size: how many duplicate groups to return per page (1-200, default 50). A scan stores at most 200 groups, so limit=200 returns the whole result in one page."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests permitted in the current window."
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining in the current window."
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds until the current window resets."
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "dedupeJob"
                  ],
                  "properties": {
                    "dedupeJob": {
                      "type": "object",
                      "required": [
                        "jobId",
                        "kind",
                        "status",
                        "scanResult",
                        "mergeResult",
                        "error"
                      ],
                      "properties": {
                        "jobId": {
                          "type": "string"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "scan",
                            "merge"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "processing",
                            "completed",
                            "failed"
                          ]
                        },
                        "scanResult": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Set only when a SCAN job is completed; null otherwise.",
                          "properties": {
                            "matchFields": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "totalGroups": {
                              "type": "integer"
                            },
                            "totalDuplicateContacts": {
                              "type": "integer"
                            },
                            "totalContactsScanned": {
                              "type": "integer"
                            },
                            "truncated": {
                              "type": "boolean",
                              "description": "True when more than 200 groups were found and only the first 200 are stored."
                            },
                            "skippedOversizedGroups": {
                              "type": "integer",
                              "description": "Groups skipped for exceeding 50 contacts (almost certainly a too-weak field selection)."
                            },
                            "pagination": {
                              "type": "object",
                              "description": "Paging over the STORED groups (at most 200). totalRecords counts pageable groups; totalGroups above counts every group found.",
                              "properties": {
                                "pageNum": {
                                  "type": "integer"
                                },
                                "totalPages": {
                                  "type": "integer"
                                },
                                "totalRecords": {
                                  "type": "integer"
                                }
                              }
                            },
                            "groups": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "groupId": {
                                    "type": "string",
                                    "description": "Stable 16-hex id — what POST /business/contacts/dedupe-merge selects by."
                                  },
                                  "matchedValues": {
                                    "type": "object",
                                    "description": "The normalized values the group matched on, keyed by match field.",
                                    "additionalProperties": {
                                      "type": "string"
                                    }
                                  },
                                  "groupSize": {
                                    "type": "integer"
                                  },
                                  "contactIds": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "lists": {
                                    "type": "array",
                                    "description": "Lists the members live in (first 10, alphabetical); listCount is the full total.",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "id": {
                                          "type": "string"
                                        },
                                        "name": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  },
                                  "listCount": {
                                    "type": "integer"
                                  },
                                  "mergePreview": {
                                    "type": "object",
                                    "description": "What the surviving contact will look like after the merge.",
                                    "properties": {
                                      "winnerContactId": {
                                        "type": "string"
                                      },
                                      "firstName": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "lastName": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "jobTitle": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "linkedinUrl": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "industry": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "kind": {
                                        "type": "string",
                                        "enum": [
                                          "canonical",
                                          "custom"
                                        ]
                                      },
                                      "companyName": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "companyDomain": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "location": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "primaryEmail": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "emailCount": {
                                        "type": "integer"
                                      },
                                      "emails": {
                                        "type": "array",
                                        "items": {
                                          "type": "object",
                                          "properties": {
                                            "email": {
                                              "type": "string"
                                            },
                                            "status": {
                                              "type": [
                                                "string",
                                                "null"
                                              ]
                                            },
                                            "isPersonal": {
                                              "type": "boolean"
                                            }
                                          }
                                        }
                                      },
                                      "primaryPhone": {
                                        "type": [
                                          "string",
                                          "null"
                                        ]
                                      },
                                      "phoneCount": {
                                        "type": "integer"
                                      },
                                      "phones": {
                                        "type": "array",
                                        "items": {
                                          "type": "object",
                                          "properties": {
                                            "phoneNumber": {
                                              "type": "string"
                                            },
                                            "status": {
                                              "type": [
                                                "string",
                                                "null"
                                              ]
                                            }
                                          }
                                        }
                                      }
                                    }
                                  },
                                  "contacts": {
                                    "type": "array",
                                    "description": "Preview of the first 25 members (contactIds carries every member).",
                                    "items": {
                                      "type": "object",
                                      "properties": {
                                        "contactId": {
                                          "type": "string"
                                        },
                                        "firstName": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "lastName": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "jobTitle": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "linkedinUrl": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "kind": {
                                          "type": "string",
                                          "enum": [
                                            "canonical",
                                            "custom"
                                          ]
                                        },
                                        "companyName": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "companyDomain": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "createdAt": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "location": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "primaryEmail": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "emailCount": {
                                          "type": "integer"
                                        },
                                        "emails": {
                                          "type": "array",
                                          "items": {
                                            "type": "object"
                                          }
                                        },
                                        "primaryPhone": {
                                          "type": [
                                            "string",
                                            "null"
                                          ]
                                        },
                                        "phoneCount": {
                                          "type": "integer"
                                        },
                                        "phones": {
                                          "type": "array",
                                          "items": {
                                            "type": "object"
                                          }
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "mergeResult": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Set only when a MERGE job is completed; null otherwise.",
                          "properties": {
                            "mergedGroups": {
                              "type": "integer"
                            },
                            "archivedContacts": {
                              "type": "integer"
                            },
                            "skippedGroups": {
                              "type": "integer",
                              "description": "Groups that merged nothing: fewer than two live members when the merge ran, or conflicting Fuse identities."
                            }
                          }
                        },
                        "error": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "DEDUPE_FAILED",
                            null
                          ]
                        }
                      }
                    }
                  }
                },
                "example": {
                  "dedupeJob": {
                    "jobId": "68a1f5209c41d20014b3eb11",
                    "kind": "scan",
                    "status": "completed",
                    "scanResult": {
                      "matchFields": [
                        "email"
                      ],
                      "totalGroups": 1,
                      "totalDuplicateContacts": 2,
                      "totalContactsScanned": 4056,
                      "truncated": false,
                      "skippedOversizedGroups": 0,
                      "pagination": {
                        "pageNum": 1,
                        "totalPages": 1,
                        "totalRecords": 1
                      },
                      "groups": [
                        {
                          "groupId": "3f6c2a9d1b8e4c7f",
                          "matchedValues": {
                            "email": "ada@brightpay.com"
                          },
                          "groupSize": 2,
                          "contactIds": [
                            "68a1f2c89c41d20014b3e955",
                            "68a1f2c89c41d20014b3e956"
                          ],
                          "lists": [
                            {
                              "id": "68a1f20b9c41d20014b3e901",
                              "name": "European fintech Series A"
                            }
                          ],
                          "listCount": 1,
                          "mergePreview": {
                            "winnerContactId": "68a1f2c89c41d20014b3e955",
                            "firstName": "Ada",
                            "lastName": "Nwosu",
                            "jobTitle": "Head of Payroll",
                            "linkedinUrl": "https://www.linkedin.com/in/ada-nwosu",
                            "industry": "Financial Services",
                            "kind": "canonical",
                            "companyName": "Brightpay",
                            "companyDomain": "brightpay.com",
                            "location": "Dublin, Leinster, Ireland",
                            "primaryEmail": "ada@brightpay.com",
                            "emailCount": 2,
                            "emails": [
                              {
                                "email": "ada@brightpay.com",
                                "status": "valid",
                                "isPersonal": false
                              },
                              {
                                "email": "ada.nwosu@gmail.com",
                                "status": "valid",
                                "isPersonal": true
                              }
                            ],
                            "primaryPhone": "+353871234567",
                            "phoneCount": 1,
                            "phones": [
                              {
                                "phoneNumber": "+353871234567",
                                "status": "valid"
                              }
                            ]
                          },
                          "contacts": [
                            {
                              "contactId": "68a1f2c89c41d20014b3e955",
                              "firstName": "Ada",
                              "lastName": "Nwosu",
                              "jobTitle": "Head of Payroll",
                              "linkedinUrl": "https://www.linkedin.com/in/ada-nwosu",
                              "kind": "canonical",
                              "companyName": "Brightpay",
                              "companyDomain": "brightpay.com",
                              "createdAt": "2026-05-02T09:14:33.000Z",
                              "location": "Dublin, Leinster, Ireland",
                              "primaryEmail": "ada@brightpay.com",
                              "emailCount": 1,
                              "emails": [
                                {
                                  "email": "ada@brightpay.com",
                                  "status": "valid",
                                  "isPersonal": false
                                }
                              ],
                              "primaryPhone": "+353871234567",
                              "phoneCount": 1,
                              "phones": [
                                {
                                  "phoneNumber": "+353871234567",
                                  "status": "valid"
                                }
                              ]
                            },
                            {
                              "contactId": "68a1f2c89c41d20014b3e956",
                              "firstName": "Ada",
                              "lastName": "Nwosu",
                              "jobTitle": null,
                              "linkedinUrl": null,
                              "kind": "custom",
                              "companyName": "Brightpay",
                              "companyDomain": null,
                              "createdAt": "2026-08-11T16:40:02.000Z",
                              "location": null,
                              "primaryEmail": "ada@brightpay.com",
                              "emailCount": 2,
                              "emails": [
                                {
                                  "email": "ada@brightpay.com",
                                  "status": "valid",
                                  "isPersonal": false
                                },
                                {
                                  "email": "ada.nwosu@gmail.com",
                                  "status": "valid",
                                  "isPersonal": true
                                }
                              ],
                              "primaryPhone": null,
                              "phoneCount": 0,
                              "phones": []
                            }
                          ]
                        }
                      ]
                    },
                    "mergeResult": null,
                    "error": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "description": "Polls a dedupe job started by `POST /business/contacts/dedupe-scan` or `POST /business/contacts/dedupe-merge`; `kind` says which of the two the id names. `status` moves pending > processing > completed or failed; poll every few seconds until it is terminal. On a completed scan, `scanResult` carries one PAGE of the duplicate groups (`pageNum`/`limit`, default 50 per page, largest groups first; `scanResult.pagination` says how many pages there are — page through once `status` is completed rather than re-fetching every group on every poll). Each group carries its `contactIds` (every member), `matchedValues` (the normalized values it matched on), the `lists` its members live in, a preview of up to 25 member `contacts`, and a `mergePreview` of the contact the group would merge into — its surviving `winnerContactId`, filled fields, and the combined `emails`/`phones` unions (first 10 entries each; `emailCount`/`phoneCount` are the full totals). Each group's `groupId` is what `POST /business/contacts/dedupe-merge` selects by. `totalGroups` counts every group the scan FOUND and can exceed the stored 200 (`truncated` says so); `pagination.totalRecords` counts the stored, pageable groups. On a completed merge, `mergeResult` carries `mergedGroups`, `archivedContacts` and `skippedGroups` (groups that no longer had two live members when the merge ran, or whose members' identities conflict). On `failed`, `error` is `DEDUPE_FAILED` — start a new job. Scan results expire with the job (about 24 hours); export jobs are not served here (poll GET /business/exports/{jobId}). Serves only the token owner's own jobs. Rate limit: 120 requests per minute, 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares.\n\nErrors:\n- `404` `JOB_NOT_FOUND` — No dedupe job with that id (it may have expired, belong to another workspace, or be an export job).\n- `422` `VALIDATION_FAILED` — jobId is not a 24-hex id.\n- `429` `RATE_LIMITED` — More than 120 requests per minute or 10,000 per day on the contacts bucket, which every /business/contacts endpoint shares; retry after Retry-After.\n\nRequires one of the following token scopes: contacts."
      }
    }
  },
  "components": {
    "securitySchemes": {
      "basicAuth": {
        "type": "http",
        "scheme": "basic",
        "description": "Your API token (`af_…`) as the Basic-auth username, with an empty password."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              },
              "param": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "doc_url": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "request_id": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      }
    }
  }
}
