{
  "openapi": "3.1.0",
  "info": {
    "title": "Octolane Public API",
    "version": "1.0.0",
    "description": "OpenAPI specification for Octolane public APIs. These endpoints let external systems read CRM data and create or update accounts, contacts, opportunities, notes, and activities through the public API gateway.",
    "contact": {
      "name": "Octolane",
      "url": "https://octolane.com"
    }
  },
  "servers": [
    {
      "url": "https://api.octolane.com",
      "description": "Public API gateway"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "CRM",
      "description": "Public endpoints for creating, bulk creating, listing, searching, and updating CRM data."
    }
  ],
  "paths": {
    "/v1/accounts": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listAccountsV1",
        "summary": "Cursor-list accounts",
        "description": "Returns accounts using cursor pagination with optional search and field projection. Custom attribute names and value types are returned in `data.custom_field_definitions`; keys in that map match keys under each account's `custom_fields` object.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free-text search query.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque pagination cursor returned by a previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Optional fields to include. Accepts a comma-separated string or repeated array values.",
            "schema": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Accounts were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AccountsListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "createAccountV1",
        "summary": "Create or resolve an account",
        "description": "Creates an account from a domain, or returns the existing account when the domain is already present. Additional account fields are persisted as system or custom attributes when supported.",
        "requestBody": {
          "required": true,
          "description": "Account payload.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account was created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Account was created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreateAccountsV1",
        "summary": "Bulk create or resolve accounts",
        "description": "Creates or resolves up to 100 account records in one request.",
        "requestBody": {
          "required": true,
          "description": "Array of account payloads. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AccountBulkInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accounts were created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Accounts were created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/search": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "searchAccountsV1Compatibility",
        "summary": "Search accounts",
        "description": "Search accounts with structured filters, sort, cursor pagination, and field projection. Custom attribute names and value types are returned in `data.custom_field_definitions`; keys in that map match keys under each account's `custom_fields` object.",
        "requestBody": {
          "required": true,
          "description": "Search body with optional text query, structured filters, sort, cursor pagination, and field projection.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Accounts were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/AccountsListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listContactsV1",
        "summary": "Cursor-list contacts",
        "description": "Returns contacts using cursor pagination with optional search and field projection. Custom attribute names and value types are returned in `data.custom_field_definitions`; keys in that map match keys under each contact's `custom_fields` object.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free-text search query.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque pagination cursor returned by a previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Optional fields to include. Accepts a comma-separated string or repeated array values.",
            "schema": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Contacts were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ContactsListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "createContactV1",
        "summary": "Create or resolve a contact",
        "description": "Creates a contact from an email address, or returns the existing contact when the email is already present. Optional profile fields are persisted as attributes when supported. A new contact is linked to the account for its work-email domain before the response returns (`account_id`); the account is created if the workspace has none for that domain. Personal email domains (gmail.com, outlook.com, ...) never get an account. Re-posting an existing contact retries the link.",
        "requestBody": {
          "required": true,
          "description": "Contact payload.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact was created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Contact was created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreateContactsV1",
        "summary": "Bulk create or resolve contacts",
        "description": "Creates or resolves up to 100 contact records in one request. New contacts are linked to the account for their work-email domain before the response returns; the account is created if the workspace has none for that domain. Personal email domains never get an account.",
        "requestBody": {
          "required": true,
          "description": "Array of contact payloads. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ContactBulkInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contacts were created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Contacts were created or resolved.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/search": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "searchContactsV1Compatibility",
        "summary": "Search contacts",
        "description": "Search contacts with structured filters, sort, cursor pagination, and field projection. Custom attribute names and value types are returned in `data.custom_field_definitions`; keys in that map match keys under each contact's `custom_fields` object.",
        "requestBody": {
          "required": true,
          "description": "Search body with optional text query, structured filters, sort, cursor pagination, and field projection.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contacts were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/ContactsListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/opportunities": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listOpportunitiesV1",
        "summary": "Cursor-list opportunities",
        "description": "Returns opportunities in a required pipeline using cursor pagination with optional stage, search, and field projection. Custom attribute names and value types are returned in `data.custom_field_definitions`; keys in that map match keys under each opportunity's `custom_fields` object.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "query",
            "required": true,
            "description": "Pipeline ID. Required for opportunity reads.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "stage_id",
            "in": "query",
            "required": false,
            "description": "Optional stage ID.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free-text search query.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Opaque pagination cursor returned by a previous page.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of records.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500
            }
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Optional fields to include. Accepts a comma-separated string or repeated array values.",
            "schema": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Opportunities were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/OpportunitiesListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "createOpportunityV1",
        "summary": "Create an opportunity",
        "description": "Creates an opportunity in a pipeline and resolves related account, primary contact, additional contacts, owner, and stage from the supplied identifiers. Duplicate rule, shared by `/v1/opportunities`, `/v1/opportunities/bulk` and `/v1/opportunities/fast-bulk`: within a pipeline, an item duplicates an existing opportunity linked to the same account domain (compared as the root domain, so `https://www.acme.com` matches `acme.com`) or, when the item has no domain, one with the same name (case and whitespace insensitive). An item with neither is matched on the name it will be created with, derived from its primary contact's email domain (`alice@acme.com` becomes `Acme Deal`); an item with no domain, name or contact is always created. A duplicate is never merged into the existing opportunity and none of its fields are applied; use `PATCH /v1/opportunities/bulk` to change the existing one. Concurrent creates of the same key are serialized across all three endpoints, so at most one opportunity is created. A duplicate answers 409.",
        "requestBody": {
          "required": true,
          "description": "Opportunity payload.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpportunityInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Opportunity was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Opportunity was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "409": {
            "description": "An opportunity matching the duplicate rule already exists. Nothing was created or changed; `errors.existing_opportunity_id` names the existing opportunity.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/opportunities/search": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "searchOpportunitiesV1Compatibility",
        "summary": "Search opportunities",
        "description": "Search opportunities with optional pipeline scope, stage, structured filters, sort, cursor pagination, and field projection. `pipeline_id` is optional; when omitted the search spans every pipeline in the org. Custom attribute names and value types are returned in `data.custom_field_definitions`; keys in that map match keys under each opportunity's `custom_fields` object.",
        "requestBody": {
          "required": true,
          "description": "Opportunity search body. `pipeline_id` is optional; omit it to search across all pipelines.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpportunitySearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Opportunities were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/OpportunitiesListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/opportunities/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreateOpportunitiesV1",
        "summary": "Bulk create opportunities",
        "description": "Creates up to 100 opportunities using the standard opportunity payload shape. Duplicate rule, shared by `/v1/opportunities`, `/v1/opportunities/bulk` and `/v1/opportunities/fast-bulk`: within a pipeline, an item duplicates an existing opportunity linked to the same account domain (compared as the root domain, so `https://www.acme.com` matches `acme.com`) or, when the item has no domain, one with the same name (case and whitespace insensitive). An item with neither is matched on the name it will be created with, derived from its primary contact's email domain (`alice@acme.com` becomes `Acme Deal`); an item with no domain, name or contact is always created. A duplicate is never merged into the existing opportunity and none of its fields are applied; use `PATCH /v1/opportunities/bulk` to change the existing one. Concurrent creates of the same key are serialized across all three endpoints, so at most one opportunity is created. Duplicates of an existing opportunity, or of an earlier item in the same request, are skipped and listed in `skipped` with the opportunity they matched; the other items are created.",
        "requestBody": {
          "required": true,
          "description": "Array of opportunity payloads. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/OpportunityBulkInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Opportunities were created or skipped as duplicates.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/OpportunityBulkCreateResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Opportunities were created or skipped as duplicates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/opportunities/fast-bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "fastBulkCreateOpportunitiesV1",
        "summary": "Fast bulk create opportunities",
        "description": "Creates up to 100 opportunities with nested account and contact payloads. This optimized endpoint batch-resolves accounts, contacts, owners, and stages before inserting opportunities. An item whose `owner_id` / `owner_email` is not a workspace member rejects the request with 422 before anything is created. Duplicate rule, shared by `/v1/opportunities`, `/v1/opportunities/bulk` and `/v1/opportunities/fast-bulk`: within a pipeline, an item duplicates an existing opportunity linked to the same account domain (compared as the root domain, so `https://www.acme.com` matches `acme.com`) or, when the item has no domain, one with the same name (case and whitespace insensitive). An item with neither is matched on the name it will be created with, derived from its primary contact's email domain (`alice@acme.com` becomes `Acme Deal`); an item with no domain, name or contact is always created. A duplicate is never merged into the existing opportunity and none of its fields are applied; use `PATCH /v1/opportunities/bulk` to change the existing one. Concurrent creates of the same key are serialized across all three endpoints, so at most one opportunity is created. The domain is `related_objects.account.domain`. Duplicates are skipped and reported exactly as in `/v1/opportunities/bulk`.",
        "requestBody": {
          "required": true,
          "description": "Array of fast bulk opportunity payloads. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FastBulkOpportunityBulkInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Opportunities were created or skipped as duplicates.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/OpportunityBulkCreateResult"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Opportunities were created or skipped as duplicates.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/activities/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreateActivitiesV1",
        "summary": "Bulk create activities",
        "description": "Creates up to 100 timeline activities such as email, meeting, call, link click, or other interaction records. `created_at` must not be in the future (a few minutes of clock skew is tolerated); a later value rejects the request with 422. Activities never create accounts or contacts: participants are matched to existing contacts, and any participant email with no contact is listed in that item's `unknown_participants`.",
        "requestBody": {
          "required": true,
          "description": "Array of activity payloads. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ActivityBulkInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Activities were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Activities were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/notes": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listNotesV1",
        "summary": "List notes",
        "description": "Returns notes for the authenticated organization.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Free-text search query.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Page size.",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Notes were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "createNoteV1",
        "summary": "Create a note",
        "description": "Creates a note and optionally links it to existing accounts by domain and existing contacts by email. Notes never create accounts or contacts: if any `account_domains` or `contact_emails` entry matches no record in the workspace, the request is rejected with 404, the response lists the unknown entries in `errors.unknown_entities`, and no note is created.",
        "requestBody": {
          "required": true,
          "description": "Note payload.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Note was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Note was created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/notes/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreateNotesV1",
        "summary": "Bulk create notes",
        "description": "Creates up to 100 notes and links each to existing accounts (by domain) and contacts (by email). Notes never create accounts or contacts: an item naming a domain or email that matches no record is not created and comes back with an empty `note_id` and `unknown_entities`, the same rule as the single-note 404. Domains are matched as their root domain (`https://www.acme.com/x` matches `acme.com`) and automated no-reply emails are ignored.",
        "requestBody": {
          "required": true,
          "description": "Array of note payloads. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/NoteBulkInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Notes were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Notes were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listPipelinesV1",
        "summary": "List pipelines",
        "description": "Returns opportunity pipelines and their stages for the authenticated organization.",
        "responses": {
          "200": {
            "description": "Pipelines were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/fields": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listAccountFieldsV1",
        "summary": "List account fields",
        "description": "Returns account field definitions, including system fields and custom fields. Use `property_name` as the stable key for custom field values.",
        "responses": {
          "200": {
            "description": "Account fields were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/FieldsListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/fields/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreateAccountFieldsV1",
        "summary": "Bulk create account fields",
        "description": "Creates account custom field definitions in bulk.",
        "requestBody": {
          "required": true,
          "description": "Array of field definitions to create. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkCreateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account fields were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Account fields were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkDeleteAccountFieldsV1",
        "summary": "Bulk delete account fields",
        "description": "Soft-deletes account custom fields in bulk. Each item identifies one field by `id`, `attribute_id`, or `property_name`. System fields cannot be deleted.",
        "requestBody": {
          "required": true,
          "description": "Array of field delete selectors. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkDeleteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account fields were deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/fields/bulk/update": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkUpdateAccountFieldsV1",
        "summary": "Bulk update account fields",
        "description": "Updates account field definitions in bulk. Identify each field by `id` or `property_name`. `property_name` is a stable identifier and cannot be renamed; if you include it with `id`, it must match the stored field `property_name` exactly.",
        "requestBody": {
          "required": true,
          "description": "Array of field definition patches. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Account fields were updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/fields": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listContactFieldsV1",
        "summary": "List contact fields",
        "description": "Returns contact field definitions, including system fields and custom fields. Use `property_name` as the stable key for custom field values.",
        "responses": {
          "200": {
            "description": "Contact fields were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/FieldsListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/fields/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreateContactFieldsV1",
        "summary": "Bulk create contact fields",
        "description": "Creates contact custom field definitions in bulk.",
        "requestBody": {
          "required": true,
          "description": "Array of field definitions to create. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkCreateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact fields were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Contact fields were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkDeleteContactFieldsV1",
        "summary": "Bulk delete contact fields",
        "description": "Soft-deletes contact custom fields in bulk. Each item identifies one field by `id`, `attribute_id`, or `property_name`. System fields cannot be deleted.",
        "requestBody": {
          "required": true,
          "description": "Array of field delete selectors. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkDeleteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact fields were deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/contacts/fields/bulk/update": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkUpdateContactFieldsV1",
        "summary": "Bulk update contact fields",
        "description": "Updates contact field definitions in bulk. Identify each field by `id` or `property_name`. `property_name` is a stable identifier and cannot be renamed; if you include it with `id`, it must match the stored field `property_name` exactly.",
        "requestBody": {
          "required": true,
          "description": "Array of field definition patches. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Contact fields were updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines/{pipeline_id}/fields": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listPipelineFieldsV1",
        "summary": "List pipeline fields",
        "description": "Returns opportunity field definitions for a pipeline, including system fields and custom fields.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pipeline fields were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/FieldsListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines/{pipeline_id}/fields/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreatePipelineFieldsV1",
        "summary": "Bulk create pipeline fields",
        "description": "Creates opportunity custom field definitions for a pipeline in bulk.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of field definitions to create. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkCreateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pipeline fields were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Pipeline fields were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkDeletePipelineFieldsV1",
        "summary": "Bulk delete pipeline fields",
        "description": "Soft-deletes opportunity custom fields for one pipeline in bulk. Each item identifies one field by `id`, `attribute_id`, or `property_name`. System fields cannot be deleted. Filters, sortings, and display settings referencing deleted fields are removed.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of field delete selectors. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkDeleteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pipeline fields were deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines/{pipeline_id}/fields/bulk/update": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkUpdatePipelineFieldsV1",
        "summary": "Bulk update pipeline fields",
        "description": "Updates opportunity field definitions for a pipeline in bulk. Identify each field by `id`/`attribute_id` or `property_name`. Opportunity fields are pipeline-scoped, so use this pipeline endpoint. `property_name` is a stable identifier and cannot be renamed; if you include it with `id`/`attribute_id`, it must match the stored field `property_name` exactly.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of field definition patches. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldBulkUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pipeline fields were updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines/{pipeline_id}/stages": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "listPipelineStagesV1",
        "summary": "List pipeline stages",
        "description": "Returns active stages for a pipeline ordered by `stage_order`.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pipeline stages were returned.",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ApiResponse"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "data": {
                          "$ref": "#/components/schemas/StagesListData"
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines/{pipeline_id}/stages/bulk": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkCreatePipelineStagesV1",
        "summary": "Bulk create pipeline stages",
        "description": "Creates stages for a pipeline in bulk.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of pipeline stages to create. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StageBulkCreateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pipeline stages were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "201": {
            "description": "Pipeline stages were created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines/{pipeline_id}/stages/bulk/update": {
      "post": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkUpdatePipelineStagesV1",
        "summary": "Bulk update pipeline stages",
        "description": "Updates stages for a pipeline in bulk.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of pipeline stage patches. Maximum 100 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StageBulkUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pipeline stages were updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pipelines/{pipeline_id}/stages/{stage_id}": {
      "delete": {
        "tags": [
          "CRM"
        ],
        "operationId": "deletePipelineStageV1",
        "summary": "Soft delete a pipeline stage",
        "description": "Soft deletes a stage in a pipeline. If deals are in that stage, they are reassigned to `destination_stage_id` when supplied, otherwise to the best remaining stage in the pipeline.",
        "parameters": [
          {
            "name": "pipeline_id",
            "in": "path",
            "required": true,
            "description": "Pipeline ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "stage_id",
            "in": "path",
            "required": true,
            "description": "Stage ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "destination_stage_id",
            "in": "query",
            "required": false,
            "description": "Optional stage ID to receive deals from the deleted stage.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Pipeline stage was deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/{object_type}/bulk": {
      "patch": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkUpdateObjectsV1",
        "summary": "Bulk update accounts, contacts, or opportunities",
        "description": "Updates up to 50 existing objects. The request body is keyed by object UUID, and each value is a patch object of field names to updated values. Field names can be either the names the read endpoints return (for example `name`, `industry`, `first_name`, `stage_id`, `amount`, `close_date`, `next_steps`) or the underlying `property_name` (`company_name`, `people_first_name`, `opportunity_stage`, `opportunity_deal_size`, `opportunity_close_date`, `opportunity_next_step`); see `BulkUpdateInput` for the full mapping. Custom fields are keyed by their `property_name` from `custom_field_definitions`. Sending both names for the same field in one item is rejected. Each item succeeds or fails on its own: the response lists one result per id with `success`, `statusCode` and, on failure, a `message` naming the rejected field and why. The top-level status is 200 when every item succeeded, 207 when some did, and 422 when none did. For opportunity relationship fields, `opportunity_account`, `opportunity_contact`, and `opportunity_other_stakeholders` use replace semantics: supplying the field clears the existing mapping of that type, then writes the supplied UUID or UUID list. Use `null` to clear `opportunity_account` or `opportunity_contact`; use `null` or `[]` to clear `opportunity_other_stakeholders`. Every supplied account or contact UUID must belong to an existing record in the workspace; an unknown UUID fails that item with 404 and nothing is written for it.",
        "parameters": [
          {
            "name": "object_type",
            "in": "path",
            "required": true,
            "description": "Object collection to update.",
            "schema": {
              "type": "string",
              "enum": [
                "accounts",
                "contacts",
                "opportunities"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Object keyed by target object UUID. Maximum 50 keys.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkUpdateInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Objects were updated.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "CRM"
        ],
        "operationId": "bulkDeleteObjectsV1",
        "summary": "Bulk delete accounts, contacts, or opportunities",
        "description": "Deletes up to 500 existing objects. Accounts can be selected by `company_id` or `domain`; account domains accept plain domains or URLs and are normalized before lookup, for example `https://www.qualcomm.com` becomes `qualcomm.com`. Contacts can be selected by `people_id` or `email`; opportunities by `opportunity_id` or exact `name`. Opportunity name matching is exact after trimming and case folding, and all active opportunities matching a supplied name are deleted.",
        "parameters": [
          {
            "name": "object_type",
            "in": "path",
            "required": true,
            "description": "Object collection to delete.",
            "schema": {
              "type": "string",
              "enum": [
                "accounts",
                "contacts",
                "opportunities"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "description": "Array of delete selectors. Maximum 500 items.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BulkDeleteInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Objects were deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/{object_type}/{object_id}/history": {
      "get": {
        "tags": [
          "CRM"
        ],
        "operationId": "getRecordHistoryV1",
        "summary": "Get record field history",
        "description": "Returns the field-change history for a record, newest first. Each entry includes the field (`property_name` plus a display `property_label`), the previous and new values (with `old_value_label`/`new_value_label` resolved for reference values such as deal stages and accounts), the author (`user` is the person when one was involved; it is null when no person wrote the row; a write made through this API is authored by the member who created the API key), the `source` naming which surface made the change (`user_web`, `public_api`, `mcp`, `chat`, `workflow`, `enrichment`, `integration_sync`, `csv_import`, `system`, or null for entries predating the field) plus `source_api_key_id` identifying which API key wrote when `source` is `public_api`, `change_kind` (`created` for a value the record was created with, `updated`, or `linked`/`unlinked` for a single deal stakeholder; null for entries predating the field), `metadata` (`tool` and `mcp_key_id` naming the agent tool and connection for `mcp` writes, `defaulted` when the system filled a creation value in), and the change timestamp. Account, contact, stakeholder and owner values on deals are labelled too. Filter to a single field with `property_name`.",
        "parameters": [
          {
            "name": "object_type",
            "in": "path",
            "required": true,
            "description": "Record type.",
            "schema": {
              "type": "string",
              "enum": [
                "accounts",
                "contacts",
                "opportunities"
              ]
            }
          },
          {
            "name": "object_id",
            "in": "path",
            "required": true,
            "description": "Record ID.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "property_name",
            "in": "query",
            "required": false,
            "description": "Restrict history to a single field (the field's stable property name).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number, newest changes first.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Entries per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Record history was returned.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiResponse"
                }
              }
            }
          },
          "400": {
            "description": "The request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing, invalid, or not allowed to access this route.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "The route rate limit was exceeded.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "Personal API key. Requests act as the workspace member who created the key, with that member's current access, and stop working when the key is disabled or its creator leaves the workspace."
      }
    },
    "schemas": {
      "ApiResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message": {
            "type": "string"
          },
          "data": {
            "description": "Endpoint-specific response payload."
          }
        },
        "additionalProperties": true
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "message": {
            "type": "string",
            "example": "Validation failed"
          },
          "statusCode": {
            "type": "integer",
            "example": 400
          }
        },
        "additionalProperties": true
      },
      "AttributeType": {
        "type": "string",
        "enum": [
          "string",
          "number",
          "checkbox",
          "date",
          "date_range",
          "rating",
          "timestamp",
          "select",
          "multi_select",
          "currency",
          "percentage",
          "location",
          "time",
          "datetime",
          "email",
          "phone",
          "website",
          "url",
          "radio",
          "team_members"
        ]
      },
      "FieldDefinition": {
        "type": "object",
        "description": "Field or attribute definition. Account/contact fields use `id`; pipeline fields use `attribute_id`. Use `property_name` as the stable API key.",
        "required": [
          "property_name",
          "current_name",
          "attribute_type"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "attribute_id": {
            "type": "string",
            "format": "uuid"
          },
          "property_name": {
            "type": "string",
            "example": "customer_tier_123"
          },
          "current_name": {
            "type": "string",
            "example": "Customer Tier"
          },
          "original_name": {
            "type": "string",
            "example": "Customer Tier"
          },
          "attribute_type": {
            "$ref": "#/components/schemas/AttributeType"
          },
          "entity_type": {
            "type": "string",
            "enum": [
              "company",
              "people",
              "opportunity"
            ]
          },
          "pipeline_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "is_editable": {
            "type": "boolean"
          },
          "is_hidden": {
            "type": "boolean"
          },
          "is_system": {
            "type": "boolean"
          },
          "attribute_order": {
            "type": "integer"
          },
          "metadata": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "additionalProperties": true
      },
      "FieldsListData": {
        "type": "object",
        "required": [
          "fields"
        ],
        "properties": {
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldDefinition"
            }
          }
        }
      },
      "FieldCreateInput": {
        "type": "object",
        "required": [
          "name",
          "attribute_type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "example": "Customer Tier"
          },
          "property_name": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]*$",
            "description": "Optional stable field key. If omitted, Octolane generates a unique property name.",
            "example": "customer_tier"
          },
          "attribute_type": {
            "$ref": "#/components/schemas/AttributeType"
          },
          "metadata": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional field metadata. For select fields, include `select_options` with label/value/color/order entries."
          },
          "order": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "is_hidden": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "FieldBulkCreateInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/FieldCreateInput"
        }
      },
      "FieldUpdateInput": {
        "type": "object",
        "description": "Field patch. Identify account/contact fields with `id` or `property_name`; identify pipeline fields with `attribute_id`/`id` or `property_name`. `property_name` is immutable: use the same value returned by the field list/create APIs. When sent together with `id` or `attribute_id`, it must match the stored field `property_name`.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "attribute_id": {
            "type": "string",
            "format": "uuid",
            "description": "Alias for `id` when updating pipeline fields."
          },
          "property_name": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]*$",
            "description": "Stable field identifier. This value cannot be changed by update APIs. If supplied with `id` or `attribute_id`, it must match the stored field `property_name` exactly."
          },
          "name": {
            "type": "string",
            "description": "New display name."
          },
          "current_name": {
            "type": "string",
            "description": "New display name."
          },
          "attribute_type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AttributeType"
              }
            ],
            "description": "Can be changed only for custom fields, not system fields."
          },
          "metadata": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ]
          },
          "order": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "is_hidden": {
            "type": "boolean"
          }
        },
        "additionalProperties": false
      },
      "FieldBulkUpdateInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/FieldUpdateInput"
        }
      },
      "FieldDeleteInput": {
        "type": "object",
        "description": "Field delete selector. Include exactly one of `id`, `attribute_id`, or `property_name`.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "attribute_id": {
            "type": "string",
            "format": "uuid",
            "description": "Alias for `id` when deleting pipeline fields."
          },
          "property_name": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]*$",
            "example": "customer_tier_123"
          }
        },
        "minProperties": 1,
        "maxProperties": 1,
        "additionalProperties": false
      },
      "FieldBulkDeleteInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/FieldDeleteInput"
        }
      },
      "StageDefinition": {
        "type": "object",
        "required": [
          "stage_id",
          "pipeline_id",
          "label",
          "stage_order"
        ],
        "properties": {
          "stage_id": {
            "type": "string",
            "format": "uuid"
          },
          "pipeline_id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "example": "Qualified"
          },
          "color": {
            "type": [
              "string",
              "null"
            ],
            "example": "#3B82F6"
          },
          "is_active": {
            "type": "boolean"
          },
          "is_default": {
            "type": "boolean"
          },
          "probability": {
            "type": "number",
            "minimum": 0,
            "maximum": 100
          },
          "stage_order": {
            "type": "integer",
            "minimum": 1
          },
          "stage_type": {
            "type": "string",
            "enum": [
              "default",
              "positive",
              "negative"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "description": "Free-text guidance for the stage. Empty or null means none."
          }
        },
        "additionalProperties": true
      },
      "StagesListData": {
        "type": "object",
        "required": [
          "stages"
        ],
        "properties": {
          "stages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StageDefinition"
            }
          }
        }
      },
      "StageCreateInput": {
        "type": "object",
        "required": [
          "label"
        ],
        "properties": {
          "label": {
            "type": "string",
            "maxLength": 255
          },
          "color": {
            "type": "string",
            "maxLength": 32
          },
          "stage_order": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "is_default": {
            "type": "boolean"
          },
          "probability": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 100
          },
          "stage_type": {
            "type": "string",
            "enum": [
              "default",
              "positive",
              "negative"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 5000,
            "description": "Free-text guidance for the stage. Leading and trailing whitespace is trimmed before the length is checked. Empty or null means none."
          }
        },
        "additionalProperties": false
      },
      "StageBulkCreateInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/StageCreateInput"
        }
      },
      "StageUpdateInput": {
        "type": "object",
        "required": [
          "stage_id"
        ],
        "properties": {
          "stage_id": {
            "type": "string",
            "format": "uuid"
          },
          "label": {
            "type": "string",
            "maxLength": 255
          },
          "color": {
            "type": "string",
            "maxLength": 32
          },
          "stage_order": {
            "type": [
              "integer",
              "null"
            ],
            "minimum": 1
          },
          "is_default": {
            "type": "boolean"
          },
          "probability": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 0,
            "maximum": 100
          },
          "stage_type": {
            "type": "string",
            "enum": [
              "default",
              "positive",
              "negative"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 5000,
            "description": "Free-text guidance for the stage. Leading and trailing whitespace is trimmed before the length is checked. Send an empty string or null to clear it."
          }
        },
        "additionalProperties": false
      },
      "StageBulkUpdateInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/StageUpdateInput"
        }
      },
      "RecordCustomFields": {
        "type": "object",
        "description": "Custom field values keyed by custom field slug. Use the sibling `custom_field_definitions` map in the same response to get each custom field's display name (`current_name`), stable property name (`property_name`), and value type (`attribute_type`).",
        "additionalProperties": true
      },
      "CustomFieldDefinition": {
        "type": "object",
        "description": "Definition for one custom field returned under a record's `custom_fields` object.",
        "required": [
          "current_name",
          "property_name",
          "attribute_type"
        ],
        "properties": {
          "current_name": {
            "type": "string",
            "description": "Display name configured for the custom field.",
            "example": "Last action date"
          },
          "property_name": {
            "type": "string",
            "description": "Stable internal property name for the custom field. This can be used in field selection, filtering, and update payloads where custom properties are accepted.",
            "example": "custom__last_action_date"
          },
          "attribute_type": {
            "type": "string",
            "description": "Value type for this custom field. Use this to format request values and interpret `custom_fields` values.",
            "enum": [
              "string",
              "number",
              "checkbox",
              "date",
              "date_range",
              "rating",
              "timestamp",
              "select",
              "multi_select",
              "currency",
              "percentage",
              "location",
              "time",
              "datetime",
              "email",
              "phone",
              "website",
              "url",
              "radio",
              "team_members"
            ],
            "example": "date"
          },
          "metadata": {
            "oneOf": [
              {
                "type": "object",
                "additionalProperties": true
              },
              {
                "type": "null"
              }
            ],
            "description": "Optional field metadata such as select options. Shape depends on `attribute_type`."
          }
        },
        "additionalProperties": false
      },
      "CustomFieldDefinitions": {
        "type": "object",
        "description": "Map of custom field slug to definition. This is returned by `/v1/accounts`, `/v1/accounts/search`, `/v1/contacts`, `/v1/contacts/search`, `/v1/opportunities`, and `/v1/opportunities/search`. The map key matches the key used under each record's `custom_fields` object. If the request uses `fields`, only selected custom fields are included; otherwise all visible custom fields for the object are included. For opportunities, definitions are scoped to the requested `pipeline_id`.",
        "additionalProperties": {
          "$ref": "#/components/schemas/CustomFieldDefinition"
        },
        "example": {
          "last_action_date": {
            "current_name": "Last Action Date",
            "property_name": "custom__last_action_date",
            "attribute_type": "date",
            "metadata": null
          },
          "kola": {
            "current_name": "Kola",
            "property_name": "custom__kola",
            "attribute_type": "multi_select",
            "metadata": {
              "options": [
                {
                  "label": "E",
                  "value": "e-532837",
                  "color": "indigo"
                }
              ]
            }
          }
        }
      },
      "CursorPageFields": {
        "type": "object",
        "properties": {
          "custom_field_definitions": {
            "$ref": "#/components/schemas/CustomFieldDefinitions"
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether another page is available."
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cursor to pass on the next request when `has_more` is true."
          },
          "limit": {
            "type": "integer",
            "description": "Effective page size used for this response."
          }
        }
      },
      "AccountRecord": {
        "type": "object",
        "description": "Account record. Additional selected system fields may be present.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "domain": {
            "type": [
              "string",
              "null"
            ]
          },
          "custom_fields": {
            "$ref": "#/components/schemas/RecordCustomFields"
          }
        },
        "additionalProperties": true
      },
      "ContactRecord": {
        "type": "object",
        "description": "Contact record. Additional selected system fields may be present.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "first_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "custom_fields": {
            "$ref": "#/components/schemas/RecordCustomFields"
          }
        },
        "additionalProperties": true
      },
      "AdditionalOpportunityContact": {
        "type": "object",
        "properties": {
          "contact_id": {
            "type": "string",
            "format": "uuid"
          },
          "contact_first_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_last_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "contact_email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          }
        },
        "additionalProperties": false
      },
      "OpportunityRecord": {
        "type": "object",
        "description": "Opportunity record. Additional selected system fields may be present.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "pipeline_id": {
            "type": "string",
            "format": "uuid"
          },
          "stage_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "stage_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "contact_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "additional_contacts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AdditionalOpportunityContact"
            }
          },
          "custom_fields": {
            "$ref": "#/components/schemas/RecordCustomFields"
          }
        },
        "additionalProperties": true
      },
      "AccountsListData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageFields"
          },
          {
            "type": "object",
            "required": [
              "accounts",
              "custom_field_definitions",
              "has_more",
              "next_cursor",
              "limit"
            ],
            "properties": {
              "accounts": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AccountRecord"
                }
              }
            }
          }
        ]
      },
      "ContactsListData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageFields"
          },
          {
            "type": "object",
            "required": [
              "contacts",
              "custom_field_definitions",
              "has_more",
              "next_cursor",
              "limit"
            ],
            "properties": {
              "contacts": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ContactRecord"
                }
              }
            }
          }
        ]
      },
      "OpportunitiesListData": {
        "allOf": [
          {
            "$ref": "#/components/schemas/CursorPageFields"
          },
          {
            "type": "object",
            "required": [
              "opportunities",
              "custom_field_definitions",
              "has_more",
              "next_cursor",
              "limit"
            ],
            "properties": {
              "opportunities": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/OpportunityRecord"
                }
              }
            }
          }
        ]
      },
      "AccountInput": {
        "type": "object",
        "required": [
          "domain"
        ],
        "properties": {
          "domain": {
            "type": "string",
            "description": "Company domain.",
            "example": "acme.com"
          },
          "name": {
            "type": [
              "string",
              "null"
            ],
            "example": "Acme"
          },
          "industry": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo": {
            "type": [
              "string",
              "null"
            ]
          },
          "linkedin": {
            "type": [
              "string",
              "null"
            ]
          },
          "twitter": {
            "type": [
              "string",
              "null"
            ]
          },
          "twitter_followers": {
            "type": [
              "number",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "primary_location": {
            "type": [
              "string",
              "null"
            ]
          },
          "founded": {
            "type": [
              "number",
              "null"
            ],
            "minimum": 1000,
            "maximum": 9999
          },
          "estimated_revenue": {
            "type": [
              "number",
              "null"
            ]
          },
          "total_fund_raised": {
            "type": [
              "number",
              "null"
            ]
          },
          "employee_range": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "tags": {
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "first_email_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "last_email_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "first_meeting_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "last_meeting_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "last_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "next_meeting": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          }
        },
        "additionalProperties": true
      },
      "AccountBulkInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/AccountInput"
        }
      },
      "ContactInput": {
        "type": "object",
        "required": [
          "email"
        ],
        "properties": {
          "email": {
            "type": "string",
            "format": "email",
            "example": "jane@acme.com"
          },
          "first_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "full_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "job_title": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "seniority": {
            "type": [
              "string",
              "null"
            ]
          },
          "linkedin": {
            "type": [
              "string",
              "null"
            ]
          },
          "twitter": {
            "type": [
              "string",
              "null"
            ]
          },
          "twitter_followers": {
            "type": [
              "number",
              "null"
            ]
          },
          "current_company": {
            "type": [
              "string",
              "null"
            ]
          },
          "other_emails": {
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "type": {
            "type": [
              "string",
              "null"
            ]
          },
          "avatar_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "email_verified": {
            "type": [
              "boolean",
              "null"
            ]
          },
          "first_email_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "last_email_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "first_meeting_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "last_meeting_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "last_interaction": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          },
          "next_meeting": {
            "$ref": "#/components/schemas/PayloadTimestamp"
          }
        },
        "additionalProperties": true
      },
      "ContactBulkInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/ContactInput"
        }
      },
      "OpportunityInput": {
        "type": "object",
        "required": [
          "pipeline_id",
          "opportunity",
          "related_objects"
        ],
        "properties": {
          "pipeline_id": {
            "type": "string",
            "format": "uuid",
            "description": "Target pipeline ID.",
            "example": "018f13b3-8239-7ef8-a8f1-93ad10b76110"
          },
          "opportunity": {
            "$ref": "#/components/schemas/OpportunityFields"
          },
          "related_objects": {
            "$ref": "#/components/schemas/OpportunityRelatedObjects"
          }
        },
        "additionalProperties": true
      },
      "OpportunityFields": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opportunity name. Derived if omitted."
          },
          "stage_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "stage_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Stage label fallback."
          },
          "deal_size": {
            "type": [
              "number",
              "null"
            ]
          },
          "close_date": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer Unix timestamp in seconds or milliseconds; the unit is read from the value (seconds for 946684800-4102444800, milliseconds for 946684800000-4102444800000). Must fall between 2000-01-01 and 2100-01-01 UTC; anything else is rejected with 422 rather than stored as null."
          },
          "next_action_date": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Integer Unix timestamp in seconds or milliseconds; the unit is read from the value (seconds for 946684800-4102444800, milliseconds for 946684800000-4102444800000). Must fall between 2000-01-01 and 2100-01-01 UTC; anything else is rejected with 422 rather than stored as null."
          },
          "next_steps": {
            "type": [
              "string",
              "null"
            ]
          },
          "custom_attributes": {
            "type": "object",
            "additionalProperties": {
              "type": [
                "string",
                "number",
                "boolean",
                "null"
              ]
            }
          }
        },
        "additionalProperties": true
      },
      "OpportunityRelatedObjects": {
        "type": "object",
        "properties": {
          "account_domain": {
            "type": [
              "string",
              "null"
            ],
            "example": "acme.com"
          },
          "primary_contact_email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email"
          },
          "additional_contact_emails": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string",
              "format": "email"
            }
          },
          "owner_email": {
            "type": [
              "string",
              "null"
            ],
            "format": "email",
            "description": "Email of a workspace member to own the opportunity. An email that matches no member is rejected with 422; omit both owner fields to default to the workspace owner."
          },
          "owner_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid",
            "description": "User id of a workspace member to own the opportunity. An `owner_id` that is not a member is rejected with 422 even when `owner_email` matches; when both are sent they must name the same member."
          }
        },
        "additionalProperties": false
      },
      "OpportunityBulkInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/OpportunityInput"
        }
      },
      "OpportunityBulkCreateResult": {
        "type": "object",
        "properties": {
          "opportunities": {
            "type": "array",
            "description": "Created opportunities, with the request index each came from.",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "opportunity_id": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            }
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer",
                  "description": "Request index of the skipped item."
                },
                "pipeline_id": {
                  "type": "string",
                  "format": "uuid"
                },
                "name": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "duplicate_in_database",
                    "duplicate_in_payload",
                    "duplicate_in_progress",
                    "duplicate_external_id"
                  ],
                  "description": "`duplicate_in_progress`: another request was creating an opportunity with the same duplicate key at the same moment; nothing was created for this item, so retry it."
                },
                "existing_opportunity_id": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "format": "uuid",
                  "description": "The opportunity this item matched: an existing one, or the one created for `duplicate_of_index`."
                },
                "duplicate_of_index": {
                  "type": "integer",
                  "description": "For `duplicate_in_payload`: the earlier item this one repeats."
                }
              }
            }
          },
          "created_count": {
            "type": "integer"
          },
          "skipped_count": {
            "type": "integer"
          }
        }
      },
      "FastBulkOpportunityInput": {
        "type": "object",
        "required": [
          "opportunity",
          "related_objects"
        ],
        "properties": {
          "pipeline_id": {
            "type": [
              "string",
              "null"
            ],
            "format": "uuid"
          },
          "pipeline_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "opportunity": {
            "$ref": "#/components/schemas/OpportunityFields"
          },
          "related_objects": {
            "type": "object",
            "required": [],
            "properties": {
              "account": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/AccountInput"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "primary_contact": {
                "oneOf": [
                  {
                    "$ref": "#/components/schemas/ContactInput"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "additional_contacts": {
                "type": [
                  "array",
                  "null"
                ],
                "items": {
                  "$ref": "#/components/schemas/ContactInput"
                }
              },
              "owner_email": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "email"
              },
              "owner_id": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "uuid"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": true
      },
      "FastBulkOpportunityBulkInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/FastBulkOpportunityInput"
        }
      },
      "ActivityInput": {
        "type": "object",
        "required": [
          "activity_type",
          "title"
        ],
        "properties": {
          "activity_type": {
            "type": "string",
            "enum": [
              "EMAIL",
              "MEETING",
              "EMAIL_OPEN",
              "LINK_CLICK",
              "CALL",
              "COMMENT",
              "IN_PERSON_MEETING",
              "LINKEDIN_CONNECTION",
              "LINKEDIN_MESSAGE",
              "X_ACTIVITY",
              "TEXT_MESSAGE",
              "WHATSAPP_MESSAGE",
              "CONTACT_ADDED",
              "OTHER"
            ]
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "email"
            },
            "default": []
          },
          "domains": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "metadata": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          },
          "created_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the activity happened. Must not be in the future."
          }
        },
        "additionalProperties": true
      },
      "ActivityBulkInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/ActivityInput"
        }
      },
      "NoteInput": {
        "type": "object",
        "required": [
          "note"
        ],
        "properties": {
          "note": {
            "type": "object",
            "required": [
              "title"
            ],
            "properties": {
              "title": {
                "type": "string"
              },
              "content": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "additionalProperties": false
          },
          "account_domains": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string"
            }
          },
          "contact_emails": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "string",
              "format": "email"
            }
          }
        },
        "additionalProperties": true
      },
      "NoteBulkInput": {
        "type": "array",
        "minItems": 1,
        "maxItems": 100,
        "items": {
          "$ref": "#/components/schemas/NoteInput"
        }
      },
      "BulkUpdateInput": {
        "type": "object",
        "description": "Bulk update payload keyed by object UUID. Accepted field names, read-API name → property_name. Accounts: `name`→`company_name`, `domain`→`company_domain`, `industry`→`company_industry`, `description`→`company_description`, `founded`→`company_founded`, `linkedin`→`company_linkedin`, `twitter`→`company_twitter`, `twitter_followers`→`company_twitter_followers`, `primary_location`→`company_primary_location`, `estimated_revenue`→`company_estimated_revenue`, `total_fund_raised`→`company_total_fund_raised`, `employee_range`→`company_employee_range`, `type`→`company_type`. Contacts: `name`→`people_name` (split into first and last name), `first_name`→`people_first_name`, `last_name`→`people_last_name`, `account_id`→`people_account`, `job_title`→`people_job_title`, `seniority`→`people_seniority`, `linkedin`→`people_linkedin`, `twitter`→`people_twitter`, `phone`→`people_phone`, `current_company`→`people_current_company`, `other_emails`→`people_other_emails`, `type`→`people_type`. Opportunities: `name`→`opportunity_name`, `stage_id`→`opportunity_stage` (moves the opportunity to that stage's pipeline; `pipeline_id` itself is not writable), `amount`→`opportunity_deal_size` (JSON number), `probability`→`opportunity_probability` (JSON number), `close_date`→`opportunity_close_date` and `next_action_date`→`opportunity_next_action_date` (ISO 8601 string or Unix timestamp in seconds or milliseconds), `next_steps`→`opportunity_next_step`, `owner_id`→`opportunity_owner`, `account_id`→`opportunity_account`, `contact_id`→`opportunity_contact`, `additional_contacts`→`opportunity_other_stakeholders`. Read-only and rejected with a message: ids, interaction timestamps, account `logo` and `tags`, and contact `email`, `email_verified` and `avatar_url`. For opportunities, relationship updates are expressed with system field names: `opportunity_account` for the associated account UUID, `opportunity_contact` for the primary contact UUID, and `opportunity_other_stakeholders` for the complete replacement list of additional contact UUIDs. These relationship fields replace the existing mapping for that field instead of appending.",
        "minProperties": 1,
        "maxProperties": 50,
        "propertyNames": {
          "format": "uuid"
        },
        "additionalProperties": {
          "type": "object",
          "minProperties": 1,
          "description": "Patch object. For opportunity relationship fields, pass UUID strings for `opportunity_account` and `opportunity_contact`, and an array of contact UUID strings for `opportunity_other_stakeholders`.",
          "additionalProperties": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "string"
                    },
                    {
                      "type": "number"
                    }
                  ]
                }
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "examples": [
          {
            "018f13b3-8239-7ef8-a8f1-93ad10b76110": {
              "name": "Acme Enterprise"
            }
          },
          {
            "018f13b3-8239-7ef8-a8f1-93ad10b76111": {
              "opportunity_account": "018f13b3-8239-7ef8-a8f1-93ad10b76120",
              "opportunity_contact": "018f13b3-8239-7ef8-a8f1-93ad10b76121",
              "opportunity_other_stakeholders": [
                "018f13b3-8239-7ef8-a8f1-93ad10b76122",
                "018f13b3-8239-7ef8-a8f1-93ad10b76123"
              ]
            }
          }
        ]
      },
      "BulkDeleteInput": {
        "type": "array",
        "description": "Bulk delete payload. Each item must include exactly one selector supported by the selected object_type.",
        "minItems": 1,
        "maxItems": 500,
        "items": {
          "type": "object",
          "minProperties": 1,
          "maxProperties": 1,
          "properties": {
            "company_id": {
              "type": "string",
              "format": "uuid"
            },
            "domain": {
              "type": "string",
              "description": "Company domain or URL. URLs and leading `www.` are normalized before lookup.",
              "example": "https://www.acme.com"
            },
            "people_id": {
              "type": "string",
              "format": "uuid"
            },
            "email": {
              "type": "string",
              "format": "email",
              "example": "buyer@acme.com"
            },
            "opportunity_id": {
              "type": "string",
              "format": "uuid"
            },
            "name": {
              "type": "string",
              "example": "Acme renewal"
            }
          },
          "additionalProperties": false
        },
        "examples": [
          [
            {
              "domain": "https://www.acme.com"
            },
            {
              "company_id": "018f13b3-8239-7ef8-a8f1-93ad10b76110"
            }
          ],
          [
            {
              "email": "buyer@acme.com"
            },
            {
              "people_id": "018f13b3-8239-7ef8-a8f1-93ad10b76111"
            }
          ],
          [
            {
              "name": "Acme renewal"
            },
            {
              "opportunity_id": "018f13b3-8239-7ef8-a8f1-93ad10b76112"
            }
          ]
        ]
      },
      "SearchFilter": {
        "type": "object",
        "required": [
          "field"
        ],
        "properties": {
          "field": {
            "type": "string",
            "description": "Public field name, system field alias, or custom field slug."
          },
          "operator": {
            "type": "string",
            "default": "eq",
            "enum": [
              "eq",
              "neq",
              "contains",
              "not_contains",
              "starts_with",
              "ends_with",
              "in",
              "not_in",
              "gt",
              "gte",
              "lt",
              "lte",
              "between",
              "empty",
              "not_empty",
              "contains_all",
              "contains_none"
            ],
            "description": "Filter operator. For multi-value operators such as `in`, `not_in`, `between`, `contains_all`, and `contains_none`, pass an array in `value`. On select, multi-select and team-member fields: `eq`/`in` match records holding any of the values; `contains`/`contains_all` require all of them; `neq`/`not_in`/`contains_none` exclude records holding any of them; `not_contains` excludes records holding all of them; `empty`/`not_empty` test for a value. Values match an option's `value` or `label`, and an option object as returned by the read API (`{ \"value\": ... }`) is accepted too. Other operators are rejected for these fields."
          },
          "value": {
            "description": "Filter value. For date/time fields such as `created_at`, `updated_at`, `close_date`, and custom date/timestamp fields, pass an ISO 8601 date or date-time string such as `2024-06-11T01:40:00Z`; Unix timestamps such as `1718070000` are not accepted in search filters. Use an array here for multi-value operators; omit for `empty` and `not_empty`.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "number"
              },
              {
                "type": "boolean"
              },
              {
                "type": "array",
                "items": {}
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "example": {
          "field": "created_at",
          "operator": "gt",
          "value": "2024-06-11T01:40:00Z"
        },
        "additionalProperties": false
      },
      "SearchSort": {
        "type": "object",
        "required": [
          "field"
        ],
        "properties": {
          "field": {
            "type": "string"
          },
          "direction": {
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ],
            "default": "desc"
          }
        },
        "additionalProperties": false
      },
      "SearchRequest": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string"
          },
          "q": {
            "type": "string"
          },
          "filters": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/SearchFilter"
            }
          },
          "sort": {
            "oneOf": [
              {
                "type": "string",
                "pattern": "^[^:]+(?::(asc|desc))?$",
                "description": "Compact sort expression. Use `field`, `field:asc`, or `field:desc`."
              },
              {
                "$ref": "#/components/schemas/SearchSort"
              },
              {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "$ref": "#/components/schemas/SearchSort"
                }
              }
            ]
          },
          "cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 500
          },
          "fields": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "OpportunitySearchRequest": {
        "type": "object",
        "properties": {
          "pipeline_id": {
            "type": "string"
          },
          "stage_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "query": {
            "type": "string"
          },
          "q": {
            "type": "string"
          },
          "filters": {
            "type": "array",
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/SearchFilter"
            }
          },
          "sort": {
            "oneOf": [
              {
                "type": "string",
                "pattern": "^[^:]+(?::(asc|desc))?$",
                "description": "Compact sort expression. Use `field`, `field:asc`, or `field:desc`."
              },
              {
                "$ref": "#/components/schemas/SearchSort"
              },
              {
                "type": "array",
                "maxItems": 1,
                "items": {
                  "$ref": "#/components/schemas/SearchSort"
                }
              }
            ]
          },
          "cursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 500
          },
          "fields": {
            "type": "array",
            "maxItems": 100,
            "items": {
              "type": "string"
            }
          }
        },
        "additionalProperties": false
      },
      "PayloadTimestamp": {
        "oneOf": [
          {
            "type": "string",
            "format": "date-time"
          },
          {
            "type": "number",
            "description": "Unix seconds or milliseconds."
          },
          {
            "type": "null"
          }
        ]
      },
      "RecordFieldHistoryEntry": {
        "type": "object",
        "properties": {
          "property_name": {
            "type": "string",
            "description": "Stable property name of the changed field.",
            "example": "opportunity_stage"
          },
          "property_label": {
            "type": "string",
            "description": "Display label of the changed field.",
            "example": "Stage"
          },
          "old_value": {
            "description": "Wrapper around the previous raw value.",
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "value": {
                "description": "Previous raw value."
              }
            },
            "additionalProperties": true
          },
          "new_value": {
            "description": "Wrapper around the new raw value.",
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "value": {
                "description": "New raw value."
              }
            },
            "additionalProperties": true
          },
          "old_value_label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display label for the previous value. Set for reference-type values (currently opportunity stages); `null` otherwise.",
            "example": "Meeting Booked"
          },
          "new_value_label": {
            "type": [
              "string",
              "null"
            ],
            "description": "Display label for the new value. Set for reference-type values (currently opportunity stages); `null` otherwise.",
            "example": "In Conversation"
          },
          "user": {
            "type": [
              "object",
              "null"
            ],
            "description": "User who made the change. `null` for system or AI-generated changes such as enrichment and workflows.",
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "display_name": {
                "type": "string",
                "example": "One Chowdhury"
              }
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "When the change was made.",
            "example": "2026-08-13T18:48:34.509Z"
          }
        }
      },
      "RecordFieldHistoryData": {
        "type": "object",
        "properties": {
          "metadata": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer",
                "description": "Total number of history entries.",
                "example": 3
              },
              "page": {
                "type": "integer",
                "example": 1
              },
              "limit": {
                "type": "integer",
                "example": 20
              }
            }
          },
          "historicalData": {
            "type": "array",
            "description": "History entries, newest first.",
            "items": {
              "$ref": "#/components/schemas/RecordFieldHistoryEntry"
            }
          }
        }
      }
    }
  }
}
